version 2

This commit is contained in:
Rushabh Mehta 2011-09-07 17:27:20 +05:30
parent f253fa8e0b
commit 0abfaf1180
57 changed files with 3468 additions and 0 deletions

26
attribution.md Normal file
View file

@ -0,0 +1,26 @@
# Attribution
Following libraries have been used in wnframework
## Python
- Jinja2
- Markdown2
- Jinja2 Markdown2 extenion
- Redis (?)
## Javascript
- JSON2
- JQuery
- JQPlot
- History
- Suckerfish (menu)
## CSS
- Skeleton CSS:
- CSS3 Overlay:
[https://github.com/LearnBoost/CSS3-Overlay/](https://github.com/LearnBoost/CSS3-Overlay/)
[http://blog.learnboost.com/blog/a-css3-overlay-system/](http://blog.learnboost.com/blog/a-css3-overlay-system/)

245
conf/Framework.sql Normal file
View file

@ -0,0 +1,245 @@
-- Core Elements to install WNFramework
-- To be called from install.py
--
-- Table structure for table `__DocTypeCache`
--
DROP TABLE IF EXISTS `__DocTypeCache`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `__DocTypeCache` (
`name` varchar(120) DEFAULT NULL,
`modified` datetime DEFAULT NULL,
`content` text
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `__SessionCache`
--
DROP TABLE IF EXISTS `__SessionCache`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `__SessionCache` (
`user` varchar(120) DEFAULT NULL,
`country` varchar(120) DEFAULT NULL,
`cache` longtext
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `tabDocField`
--
DROP TABLE IF EXISTS `tabDocField`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tabDocField` (
`name` varchar(120) NOT NULL,
`creation` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
`modified_by` varchar(40) DEFAULT NULL,
`owner` varchar(40) DEFAULT NULL,
`docstatus` int(1) DEFAULT '0',
`parent` varchar(120) DEFAULT NULL,
`parentfield` varchar(120) DEFAULT NULL,
`parenttype` varchar(120) DEFAULT NULL,
`idx` int(8) DEFAULT NULL,
`fieldname` varchar(180) DEFAULT NULL,
`label` varchar(180) DEFAULT NULL,
`oldfieldname` varchar(180) DEFAULT NULL,
`fieldtype` varchar(180) DEFAULT NULL,
`oldfieldtype` varchar(180) DEFAULT NULL,
`options` text,
`search_index` int(3) DEFAULT NULL,
`hidden` int(3) DEFAULT NULL,
`print_hide` int(3) DEFAULT NULL,
`report_hide` int(3) DEFAULT NULL,
`reqd` int(3) DEFAULT NULL,
`no_copy` int(3) DEFAULT NULL,
`allow_on_submit` int(3) DEFAULT NULL,
`trigger` varchar(180) DEFAULT NULL,
`depends_on` varchar(180) DEFAULT NULL,
`permlevel` int(3) DEFAULT NULL,
`width` varchar(180) DEFAULT NULL,
`default` text,
`description` text,
`colour` varchar(180) DEFAULT NULL,
`icon` varchar(180) DEFAULT NULL,
`in_filter` int(3) DEFAULT NULL,
PRIMARY KEY (`name`),
KEY `parent` (`parent`),
KEY `label` (`label`),
KEY `fieldtype` (`fieldtype`),
KEY `fieldname` (`fieldname`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `tabDocFormat`
--
DROP TABLE IF EXISTS `tabDocFormat`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tabDocFormat` (
`name` varchar(120) NOT NULL,
`creation` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
`modified_by` varchar(40) DEFAULT NULL,
`owner` varchar(40) DEFAULT NULL,
`docstatus` int(1) DEFAULT '0',
`parent` varchar(120) DEFAULT NULL,
`parentfield` varchar(120) DEFAULT NULL,
`parenttype` varchar(120) DEFAULT NULL,
`idx` int(8) DEFAULT NULL,
`format` varchar(180) DEFAULT NULL,
PRIMARY KEY (`name`),
KEY `parent` (`parent`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `tabDocPerm`
--
DROP TABLE IF EXISTS `tabDocPerm`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tabDocPerm` (
`name` varchar(120) NOT NULL,
`creation` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
`modified_by` varchar(40) DEFAULT NULL,
`owner` varchar(40) DEFAULT NULL,
`docstatus` int(1) DEFAULT '0',
`parent` varchar(120) DEFAULT NULL,
`parentfield` varchar(120) DEFAULT NULL,
`parenttype` varchar(120) DEFAULT NULL,
`idx` int(8) DEFAULT NULL,
`permlevel` int(11) DEFAULT NULL,
`role` varchar(180) DEFAULT NULL,
`match` varchar(180) DEFAULT NULL,
`read` int(3) DEFAULT NULL,
`write` int(3) DEFAULT NULL,
`create` int(3) DEFAULT NULL,
`submit` int(3) DEFAULT NULL,
`cancel` int(3) DEFAULT NULL,
`amend` int(3) DEFAULT NULL,
`execute` int(3) DEFAULT NULL,
PRIMARY KEY (`name`),
KEY `parent` (`parent`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `tabDocType`
--
DROP TABLE IF EXISTS `tabDocType`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tabDocType` (
`name` varchar(180) NOT NULL DEFAULT '',
`creation` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
`modified_by` varchar(40) DEFAULT NULL,
`owner` varchar(180) DEFAULT NULL,
`docstatus` int(1) DEFAULT '0',
`parent` varchar(120) DEFAULT NULL,
`parentfield` varchar(120) DEFAULT NULL,
`parenttype` varchar(120) DEFAULT NULL,
`idx` int(8) DEFAULT NULL,
`search_fields` varchar(180) DEFAULT NULL,
`issingle` int(1) DEFAULT NULL,
`istable` int(1) DEFAULT NULL,
`version` int(11) DEFAULT NULL,
`module` varchar(180) DEFAULT NULL,
`autoname` varchar(180) DEFAULT NULL,
`name_case` varchar(180) DEFAULT NULL,
`description` text,
`colour` varchar(180) DEFAULT NULL,
`read_only` int(1) DEFAULT NULL,
`in_create` int(1) DEFAULT NULL,
`show_in_menu` int(3) DEFAULT NULL,
`menu_index` int(11) DEFAULT NULL,
`parent_node` varchar(180) DEFAULT NULL,
`smallicon` varchar(180) DEFAULT NULL,
`allow_print` int(1) DEFAULT NULL,
`allow_email` int(1) DEFAULT NULL,
`allow_copy` int(1) DEFAULT NULL,
`allow_rename` int(1) DEFAULT NULL,
`hide_toolbar` int(1) DEFAULT NULL,
`hide_heading` int(1) DEFAULT NULL,
`allow_attach` int(1) DEFAULT NULL,
`use_template` int(1) DEFAULT NULL,
`max_attachments` int(11) DEFAULT NULL,
`section_style` varchar(180) DEFAULT NULL,
`client_script` text,
`client_script_core` text,
`server_code` text,
`server_code_core` text,
`server_code_compiled` text,
`client_string` text,
`server_code_error` varchar(180) DEFAULT NULL,
`print_outline` varchar(180) DEFAULT NULL,
`dt_template` text,
`is_transaction_doc` int(1) DEFAULT NULL,
`change_log` text,
`read_only_onload` int(1) DEFAULT NULL,
PRIMARY KEY (`name`),
KEY `parent` (`parent`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `tabSeries`
--
DROP TABLE IF EXISTS `tabSeries`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tabSeries` (
`name` varchar(40) DEFAULT NULL,
`current` int(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `tabSessions`
--
DROP TABLE IF EXISTS `tabSessions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tabSessions` (
`user` varchar(40) DEFAULT NULL,
`sid` varchar(120) DEFAULT NULL,
`sessiondata` longtext,
`ipaddress` varchar(16) DEFAULT NULL,
`lastupdate` datetime DEFAULT NULL,
`status` varchar(20) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `tabSingles`
--
DROP TABLE IF EXISTS `tabSingles`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tabSingles` (
`doctype` varchar(40) DEFAULT NULL,
`field` varchar(40) DEFAULT NULL,
`value` text,
KEY `doctype` (`doctype`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

0
conf/__init__.py Normal file
View file

12
conf/_conf.py Normal file
View file

@ -0,0 +1,12 @@
# Main Configuration File
# Copy this into conf.py
# ----------------------
# Index URL
# ---------
# URL path to index.html
# if you are installing within a folder, add the folderpath
index_path = '/'

35
conf/apache.conf Normal file
View file

@ -0,0 +1,35 @@
# Sample httpd.conf extension ot start wnframework
# Port on which you want to run wnframework
Listen 8080
<VirtualHost *:8080>
# Set your root folder here
DocumentRoot /var/www/html/
<Directory />
AllowOverride All
Order allow,deny
Allow from all
# enable direct execution of .py files
Options +ExecCGI
#AddHandler cgi-script .cgi
AddHandler cgi-script .py
DirectoryIndex index.html
RewriteEngine On
# all model calls will be redirected to model.py
# to call a model - mysite/models/type/name eg. mysite.com/models/Organization/WebNotes
RewriteRule /models/(.*)$ /lib/model.py/$1 [L,QSA]
# all page calls will be redircted to page.py
# page/home
RewriteRule /pages/(.*)$ /lib/page.py/$1 [L,QSA]
</Directory>
</VirtualHost>

20
conf/app.js Normal file
View file

@ -0,0 +1,20 @@
wn.require('lib/js/lib/jquery.min.js');
wn.require('lib/js/wn/ui/status_bar.js');
wn.sb = new wn.ui.StatusBar();
wn.sb.set_value(15);
// for datepicker
wn.require('lib/js/legacy/jquery/jquery-ui.min.js')
wn.sb.set_value(25);
wn.require('lib/js/legacy/wnf.compressed.js');
wn.sb.set_value(60);
wn.require('lib/js/legacy/form.compressed.js');
wn.require('lib/js/legacy/report.compressed.js');
wn.require('lib/css/legacy/default.css');
wn.sb.set_value(80);
$(document).bind('ready', function() {
startup();
});

11
conf/conf.py Normal file
View file

@ -0,0 +1,11 @@
# Main Configuration File
# Copy this into conf.py
# ----------------------
# Index URL
# ---------
# URL path to index.html
# if you are installing within a folder, add the folderpath
index_path = '/'

21
conf/index.cgi Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/python
# main handler file
import cgi, cgitb, os, sys
cgitb.enable()
# import libs
sys.path.append('lib/py')
sys.path.append('erpnext')
import webnotes
import webnotes.defs
webnotes.form = cgi.FieldStorage()
# make the form_dict
for key in webnotes.form.keys():
webnotes.form_dict[key] = webnotes.form.getvalue(key)
# pass on to legacy handler
import webnotes.handler

389
css/base.css Executable file
View file

@ -0,0 +1,389 @@
/*
* Skeleton V1.1
* Copyright 2011, Dave Gamache
* www.getskeleton.com
* Free to use under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
* 8/17/2011
*/
/* Table of Content
==================================================
#Reset & Basics
#Basic Styles
#Site Styles
#Typography
#Links
#Lists
#Images
#Buttons
#Tabs
#Forms
#Misc */
/* #Reset & Basics (Inspired by E. Meyers)
================================================== */
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline; }
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
display: block; }
body {
line-height: 1; }
ol, ul {
list-style: none; }
blockquote, q {
quotes: none; }
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none; }
table {
border-collapse: collapse;
border-spacing: 0; }
/* #Basic Styles
================================================== */
body {
background: #fff;
font: 14px/21px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #444;
-webkit-font-smoothing: antialiased; /* Fix for webkit rendering */
-webkit-text-size-adjust: 100%;
}
/* #Typography
================================================== */
h1, h2, h3, h4, h5, h6 {
color: #181818;
font-family: "Georgia", "Times New Roman", Helvetica, Arial, sans-serif;
font-weight: normal; }
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-weight: inherit; }
h1 { font-size: 46px; line-height: 55px; margin-bottom: 14px;}
h2 { font-size: 35px; line-height: 40px; margin-bottom: 10px; }
h3 { font-size: 28px; line-height: 34px; margin-bottom: 8px; }
h4 { font-size: 21px; line-height: 30px; margin-bottom: 4px; }
h5 { font-size: 17px; line-height: 24px; }
h6 { font-size: 14px; line-height: 21px; }
.subheader { color: #777; }
p { margin: 0 0 20px 0; }
p img { margin: 0; }
p.lead { font-size: 21px; line-height: 27px; color: #777; }
em { font-style: italic; }
strong { font-weight: bold; color: #333; }
small { font-size: 80%; }
/* Blockquotes */
blockquote, blockquote p { font-size: 17px; line-height: 24px; color: #777; font-style: italic; }
blockquote { margin: 0 0 20px; padding: 9px 20px 0 19px; border-left: 1px solid #ddd; }
blockquote cite { display: block; font-size: 12px; color: #555; }
blockquote cite:before { content: "\2014 \0020"; }
blockquote cite a, blockquote cite a:visited, blockquote cite a:visited { color: #555; }
hr { border: solid #ddd; border-width: 1px 0 0; clear: both; margin: 10px 0 30px; height: 0; }
/* #Links
================================================== */
a, a:visited { color: #333; text-decoration: underline; outline: 0; }
a:hover, a:focus { color: #000; }
p a, p a:visited { line-height: inherit; }
/* #Lists
================================================== */
ul, ol { margin-bottom: 20px; }
ul { list-style: none outside; }
ol { list-style: decimal; }
ol, ul.square, ul.circle, ul.disc { margin-left: 30px; }
ul.square { list-style: square outside; }
ul.circle { list-style: circle outside; }
ul.disc { list-style: disc outside; }
ul ul, ul ol,
ol ol, ol ul { margin: 4px 0 5px 30px; font-size: 90%; }
ul ul li, ul ol li,
ol ol li, ol ul li { margin-bottom: 6px; }
li { line-height: 18px; margin-bottom: 12px; }
ul.large li { line-height: 21px; }
li p { line-height: 21px; }
/* #Images
================================================== */
img.scale-with-grid {
max-width: 100%;
height: auto; }
/* #Buttons
================================================== */
a.button,
button,
input[type="submit"],
input[type="reset"],
input[type="button"] {
background: #eee; /* Old browsers */
background: -moz-linear-gradient(top, rgba(255,255,255,.2) 0%, rgba(0,0,0,.2) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.2)), color-stop(100%,rgba(0,0,0,.2))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Opera11.10+ */
background: -ms-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* IE10+ */
background: linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* W3C */
border: 1px solid #aaa;
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
padding: 4px 12px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
color: #444;
display: inline-block;
font-size: 11px;
font-weight: bold;
text-decoration: none;
text-shadow: 0 1px rgba(255, 255, 255, .75);
cursor: pointer;
margin-bottom: 20px;
line-height: 21px;
font-family: "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; }
a.button:hover,
button:hover,
input[type="submit"]:hover,
input[type="reset"]:hover,
input[type="button"]:hover {
color: #222;
background: #ddd; /* Old browsers */
background: -moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.3)), color-stop(100%,rgba(0,0,0,.3))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Opera11.10+ */
background: -ms-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* IE10+ */
background: linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* W3C */
border: 1px solid #888;
border-top: 1px solid #aaa;
border-left: 1px solid #aaa; }
a.button:active,
button:active,
input[type="submit"]:active,
input[type="reset"]:active,
input[type="button"]:active {
border: 1px solid #666;
background: #ccc; /* Old browsers */
background: -moz-linear-gradient(top, rgba(255,255,255,.35) 0%, rgba(10,10,10,.4) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.35)), color-stop(100%,rgba(10,10,10,.4))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Opera11.10+ */
background: -ms-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* IE10+ */
background: linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* W3C */ }
.button.full-width,
button.full-width,
input[type="submit"].full-width,
input[type="reset"].full-width,
input[type="button"].full-width {
width: 100%;
padding-left: 0 !important;
padding-right: 0 !important;
text-align: center; }
/* #Tabs (activate in tabs.js)
================================================== */
ul.tabs {
display: block;
margin: 0 0 20px 0;
padding: 0;
border-bottom: solid 1px #ddd; }
ul.tabs li {
display: block;
width: auto;
height: 30px;
padding: 0;
float: left;
margin-bottom: 0; }
ul.tabs li a {
display: block;
text-decoration: none;
width: auto;
height: 29px;
padding: 0px 20px;
line-height: 30px;
border: solid 1px #ddd;
border-width: 1px 1px 0 0;
margin: 0;
background: #f5f5f5;
font-size: 13px; }
ul.tabs li a.active {
background: #fff;
height: 30px;
position: relative;
top: -4px;
padding-top: 4px;
border-left-width: 1px;
margin: 0 0 0 -1px;
color: #111;
-moz-border-radius-topleft: 2px;
-webkit-border-top-left-radius: 2px;
border-top-left-radius: 2px;
-moz-border-radius-topright: 2px;
-webkit-border-top-right-radius: 2px;
border-top-right-radius: 2px; }
ul.tabs li:first-child a.active {
margin-left: 0; }
ul.tabs li:first-child a {
border-width: 1px 1px 0 1px;
-moz-border-radius-topleft: 2px;
-webkit-border-top-left-radius: 2px;
border-top-left-radius: 2px; }
ul.tabs li:last-child a {
-moz-border-radius-topright: 2px;
-webkit-border-top-right-radius: 2px;
border-top-right-radius: 2px; }
ul.tabs-content { margin: 0; display: block; }
ul.tabs-content > li { display:none; }
ul.tabs-content > li.active { display: block; }
/* Clearfixing tabs for beautiful stacking */
ul.tabs:before,
ul.tabs:after {
content: '\0020';
display: block;
overflow: hidden;
visibility: hidden;
width: 0;
height: 0; }
ul.tabs:after {
clear: both; }
ul.tabs {
zoom: 1; }
/* #Forms
================================================== */
form {
margin-bottom: 20px; }
fieldset {
margin-bottom: 20px; }
input[type="text"],
input[type="password"],
input[type="email"],
textarea,
select {
border: 1px solid #ccc;
padding: 6px 4px;
outline: none;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
border-radius: 2px;
font: 13px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #777;
margin: 0;
width: 210px;
max-width: 100%;
display: block;
margin-bottom: 20px;
background: #fff; }
select {
padding: 0; }
input[type="text"]:focus,
input[type="password"]:focus,
input[type="email"]:focus,
textarea:focus {
border: 1px solid #aaa;
color: #444;
-moz-box-shadow: 0 0 3px rgba(0,0,0,.2);
-webkit-box-shadow: 0 0 3px rgba(0,0,0,.2);
box-shadow: 0 0 3px rgba(0,0,0,.2); }
textarea {
min-height: 60px; }
label,
legend {
display: block;
font-weight: bold;
font-size: 13px; }
select {
width: 220px; }
input[type="checkbox"] {
display: inline; }
label span,
legend span {
font-weight: normal;
font-size: 13px;
color: #444; }
/* #Misc
================================================== */
.remove-bottom { margin-bottom: 0 !important; }
.half-bottom { margin-bottom: 10px !important; }
.add-bottom { margin-bottom: 20px !important; }
/*
chaiproject.org
Some standard styles to help you get started
Fibonacchi 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
*/
/* Code blocks */
pre, code {
font: 12px 'Bitstream Vera Sans Mono','Courier',monospace;
}
/* Light Gradient */
.gradient-light {
background: #eaeaea; /* Old browsers */
background: -moz-linear-gradient(top, #eaeaea 0%, #b2b2b2 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#eaeaea), color-stop(100%,#b2b2b2)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #eaeaea 0%,#b2b2b2 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #eaeaea 0%,#b2b2b2 100%); /* Opera11.10+ */
background: -ms-linear-gradient(top, #eaeaea 0%,#b2b2b2 100%); /* IE10+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eaeaea', endColorstr='#b2b2b2',GradientType=0 ); /* IE6-9 */
background: linear-gradient(top, #eaeaea 0%,#b2b2b2 100%); /* W3C */
}
/* Dark Gradient */
.gradient-dark {
background: #45484d; /* Old browsers */
background: -moz-linear-gradient(top, #45484d 0%, #000000 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#45484d), color-stop(100%,#000000)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #45484d 0%,#000000 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #45484d 0%,#000000 100%); /* Opera11.10+ */
background: -ms-linear-gradient(top, #45484d 0%,#000000 100%); /* IE10+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#45484d', endColorstr='#000000',GradientType=0 ); /* IE6-9 */
background: linear-gradient(top, #45484d 0%,#000000 100%); /* W3C */
color: #FFF;
}
/* Small shadow */
.shadow {
-moz-box-shadow: 0px 2px 2px #888;
-webkit-box-shadow: 0px 2px 2px #888;
box-shadow: 0px 2px 2px #888;
}
/* Rounded corners */
.round {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}

58
css/layout.css Executable file
View file

@ -0,0 +1,58 @@
/*
* Skeleton V1.1
* Copyright 2011, Dave Gamache
* www.getskeleton.com
* Free to use under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
* 8/17/2011
*/
/* Table of Content
==================================================
#Site Styles
#Page Styles
#Media Queries
#Font-Face */
/* #Site Styles
================================================== */
/* #Page Styles
================================================== */
/* #Media Queries
================================================== */
/* Smaller than standard 960 (devices and browsers) */
@media only screen and (max-width: 959px) {}
/* Tablet Portrait size to standard 960 (devices and browsers) */
@media only screen and (min-width: 768px) and (max-width: 959px) {}
/* All Mobile Sizes (devices and browser) */
@media only screen and (max-width: 767px) {}
/* Mobile Landscape Size to Tablet Portrait (devices and browsers) */
@media only screen and (min-width: 480px) and (max-width: 767px) {}
/* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */
@media only screen and (max-width: 479px) {}
/* #Font-Face
================================================== */
/* This is the proper syntax for an @font-face file
Just create a "fonts" folder at the root,
copy your FontName into code below and remove
comment brackets */
/* @font-face {
font-family: 'FontName';
src: url('../fonts/FontName.eot');
src: url('../fonts/FontName.eot?iefix') format('eot'),
url('../fonts/FontName.woff') format('woff'),
url('../fonts/FontName.ttf') format('truetype'),
url('../fonts/FontName.svg#webfontZam02nTh') format('svg');
font-weight: normal;
font-style: normal; }
*/

236
css/skeleton.css vendored Executable file
View file

@ -0,0 +1,236 @@
/*
* Skeleton V1.1
* Copyright 2011, Dave Gamache
* www.getskeleton.com
* Free to use under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
* 8/17/2011
*/
/* Table of Contents
==================================================
#Base 960 Grid
#Tablet (Portrait)
#Mobile (Portrait)
#Mobile (Landscape)
#Clearing */
/* #Base 960 Grid
================================================== */
.container { position: relative; width: 960px; margin: 0 auto; padding: 0; }
.column, .columns { float: left; display: inline; margin-left: 10px; margin-right: 10px; }
.row { margin-bottom: 20px; }
/* Nested Column Classes */
.column.alpha, .columns.alpha { margin-left: 0; }
.column.omega, .columns.omega { margin-right: 0; }
/* Base Grid */
.container .one.column { width: 40px; }
.container .two.columns { width: 100px; }
.container .three.columns { width: 160px; }
.container .four.columns { width: 220px; }
.container .five.columns { width: 280px; }
.container .six.columns { width: 340px; }
.container .seven.columns { width: 400px; }
.container .eight.columns { width: 460px; }
.container .nine.columns { width: 520px; }
.container .ten.columns { width: 580px; }
.container .eleven.columns { width: 640px; }
.container .twelve.columns { width: 700px; }
.container .thirteen.columns { width: 760px; }
.container .fourteen.columns { width: 820px; }
.container .fifteen.columns { width: 880px; }
.container .sixteen.columns { width: 940px; }
.container .one-third.column { width: 300px; }
.container .two-thirds.column { width: 620px; }
/* Offsets */
.container .offset-by-one { padding-left: 60px; }
.container .offset-by-two { padding-left: 120px; }
.container .offset-by-three { padding-left: 180px; }
.container .offset-by-four { padding-left: 240px; }
.container .offset-by-five { padding-left: 300px; }
.container .offset-by-six { padding-left: 360px; }
.container .offset-by-seven { padding-left: 420px; }
.container .offset-by-eight { padding-left: 480px; }
.container .offset-by-nine { padding-left: 540px; }
.container .offset-by-ten { padding-left: 600px; }
.container .offset-by-eleven { padding-left: 660px; }
.container .offset-by-twelve { padding-left: 720px; }
.container .offset-by-thirteen { padding-left: 780px; }
.container .offset-by-fourteen { padding-left: 840px; }
.container .offset-by-fifteen { padding-left: 900px; }
/* #Tablet (Portrait)
================================================== */
/* Note: Design for a width of 768px */
@media only screen and (min-width: 768px) and (max-width: 959px) {
.container { width: 768px; }
.container .column,
.container .columns { margin-left: 10px; margin-right: 10px; }
.column.alpha, .columns.alpha { margin-left: 0; margin-right: 10px; }
.column.omega, .columns.omega { margin-right: 0; margin-left: 10px; }
.container .one.column { width: 28px; }
.container .two.columns { width: 76px; }
.container .three.columns { width: 124px; }
.container .four.columns { width: 172px; }
.container .five.columns { width: 220px; }
.container .six.columns { width: 268px; }
.container .seven.columns { width: 316px; }
.container .eight.columns { width: 364px; }
.container .nine.columns { width: 412px; }
.container .ten.columns { width: 460px; }
.container .eleven.columns { width: 508px; }
.container .twelve.columns { width: 556px; }
.container .thirteen.columns { width: 604px; }
.container .fourteen.columns { width: 652px; }
.container .fifteen.columns { width: 700px; }
.container .sixteen.columns { width: 748px; }
.container .one-third.column { width: 236px; }
.container .two-thirds.column { width: 492px; }
/* Offsets */
.container .offset-by-one { padding-left: 48px; }
.container .offset-by-two { padding-left: 96px; }
.container .offset-by-three { padding-left: 144px; }
.container .offset-by-four { padding-left: 192px; }
.container .offset-by-five { padding-left: 240px; }
.container .offset-by-six { padding-left: 288px; }
.container .offset-by-seven { padding-left: 336px; }
.container .offset-by-eight { padding-left: 348px; }
.container .offset-by-nine { padding-left: 432px; }
.container .offset-by-ten { padding-left: 480px; }
.container .offset-by-eleven { padding-left: 528px; }
.container .offset-by-twelve { padding-left: 576px; }
.container .offset-by-thirteen { padding-left: 624px; }
.container .offset-by-fourteen { padding-left: 672px; }
.container .offset-by-fifteen { padding-left: 720px; }
}
/* #Mobile (Portrait)
================================================== */
/* Note: Design for a width of 320px */
@media only screen and (max-width: 767px) {
.container { width: 300px; }
.columns, .column { margin: 0; }
.container .one.column,
.container .two.columns,
.container .three.columns,
.container .four.columns,
.container .five.columns,
.container .six.columns,
.container .seven.columns,
.container .eight.columns,
.container .nine.columns,
.container .ten.columns,
.container .eleven.columns,
.container .twelve.columns,
.container .thirteen.columns,
.container .fourteen.columns,
.container .fifteen.columns,
.container .sixteen.columns,
.container .one-third.column,
.container .two-thirds.column { width: 300px; }
/* Offsets */
.container .offset-by-one,
.container .offset-by-two,
.container .offset-by-three,
.container .offset-by-four,
.container .offset-by-five,
.container .offset-by-six,
.container .offset-by-seven,
.container .offset-by-eight,
.container .offset-by-nine,
.container .offset-by-ten,
.container .offset-by-eleven,
.container .offset-by-twelve,
.container .offset-by-thirteen,
.container .offset-by-fourteen,
.container .offset-by-fifteen { padding-left: 0; }
}
/* #Mobile (Landscape)
================================================== */
/* Note: Design for a width of 480px */
@media only screen and (min-width: 480px) and (max-width: 767px) {
.container { width: 420px; }
.columns, .column { margin: 0; }
.container .one.column,
.container .two.columns,
.container .three.columns,
.container .four.columns,
.container .five.columns,
.container .six.columns,
.container .seven.columns,
.container .eight.columns,
.container .nine.columns,
.container .ten.columns,
.container .eleven.columns,
.container .twelve.columns,
.container .thirteen.columns,
.container .fourteen.columns,
.container .fifteen.columns,
.container .sixteen.columns,
.container .one-third.column,
.container .two-thirds.column { width: 420px; }
}
/* #Clearing
================================================== */
/* Self Clearing Goodness */
.container:after { content: "\0020"; display: block; height: 0; clear: both; visibility: hidden; }
/* Use clearfix class on parent to clear nested columns,
or wrap each row of columns in a <div class="row"> */
.clearfix:before,
.clearfix:after,
.row:before,
.row:after {
content: '\0020';
display: block;
overflow: hidden;
visibility: hidden;
width: 0;
height: 0; }
.row:after,
.clearfix:after {
clear: both; }
.row,
.clearfix {
zoom: 1; }
/* You can also use a <br class="clear" /> to clear columns */
.clear {
clear: both;
display: block;
overflow: hidden;
visibility: hidden;
width: 0;
height: 0;
}

82
css/ui/overlay.css Normal file
View file

@ -0,0 +1,82 @@
/* https://github.com/LearnBoost/CSS3-Overlay/ */
body.overlaid {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
body.overlaid div.overlay {
-webkit-transform: translateY(0);
-moz-transform: translateY(0);
transform: translateY(0);
}
div.overlay {
/* using display none to hide the overlay nullifies -webkit-transition */
-webkit-transform: translateY(-50000px);
-moz-transform: translateY(-50000px);
transform: translateY(-50000px);
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: rgba(0,0,0,0.6);
-webkit-user-select: auto;
-moz-user-select: auto;
user-select: auto;
}
div.overlay > div.wrap-outer {
position: relative;
width: 100%;
height: 100%;
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-orient: horizontal;
-moz-box-orient: horizontal;
box-orient: horizontal;
-webkit-box-align: stretch;
-moz-box-align: stretch;
box-align: stretch;
-webkit-box-pack: center;
-moz-box-pack: center;
box-pack: center;
}
div.overlay > div.wrap-outer > div.wrap {
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-orient: vertical;
-moz-box-orient: vertical;
box-orient: vertical;
-webkit-box-align: stretch;
-moz-box-align: stretch;
box-align: stretch;
-webkit-box-pack: center;
-moz-box-pack: center;
box-pack: center;
}
div.overlay > div.wrap-outer > div.wrap > * {
-webkit-box-flex: 0;
-moz-box-flex: 0;
box-flex: 0;
display: block;
}
div.overlay > div.wrap-outer > div.wrap > div.dialog {
padding: 21px;
background-color: #fff;
}

19
css/ui/status_bar.css Normal file
View file

@ -0,0 +1,19 @@
div.status_bar_outer {
background-color: rgba(0,0,0,0.2);
border: 1px solid rgba(0,0,0,0.4);
height: 21px;
width: 240px;
}
div.status_bar_inner {
background: #a9e4f7; /* Old browsers */
background: -moz-linear-gradient(left, #a9e4f7 0%, #0fb4e7 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, right top, color-stop(0%,#a9e4f7), color-stop(100%,#0fb4e7)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(left, #a9e4f7 0%,#0fb4e7 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(left, #a9e4f7 0%,#0fb4e7 100%); /* Opera11.10+ */
background: -ms-linear-gradient(left, #a9e4f7 0%,#0fb4e7 100%); /* IE10+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a9e4f7', endColorstr='#0fb4e7',GradientType=1 ); /* IE6-9 */
background: linear-gradient(left, #a9e4f7 0%,#0fb4e7 100%); /* W3C */
height: 21px;
width: 0%;
}

BIN
images/icons/folder.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 996 B

BIN
images/icons/icons.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

19
js/build.json Normal file
View file

@ -0,0 +1,19 @@
{
"core.min.js": [
"wn/provide.js",
"wn/xmlhttp.js",
"wn/assets.js",
"wn/require.js",
"wn/dom.js",
"wn/page.js",
"lib/json2.js",
"core.js"
],
"lib/superfish/superfish.min.js": [
"lib/superfish/hoverIntent.js",
"lib/superfish/superfish.js",
"lib/superfish/make_superfish.js",
"lib/superfish/css/superfish.css",
"lib/superfish/css/superfish-vertical.css"
]
}

33
js/core.js Normal file
View file

@ -0,0 +1,33 @@
// load all critical libraries
wn.require("lib/js/lib/jquery.min.js");
//wn.require("lib/js/lib/history/history.min.js");
wn.require("lib/js/lib/history/history.adapter.jquery.js");
wn.require("lib/js/lib/history/history.js");
wn.require("lib/js/lib/history/history.html4.js");
wn.require("lib/js/wn/history.js");
/* overload links for ajax pages */
$(document).bind('ready', function() {
var base = window.location.href.split('#')[0];
// convert hard links to softlinks
$.each($('a[softlink!="false"]'), function(i, v) {
// if linking on the same site
if(v.href.substr(0, base.length)==base) {
var path = (v.href.substr(base.length));
// if hardlink, softlink it
if(path.substr(0,1)!='#') {
v.href = base + '#' + path;
}
}
});
// go to hash page if exists
if(window.location.hash) {
wn.page.set(window.location.hash.substr(1));
}
});

55
js/core.min.js vendored Normal file
View file

@ -0,0 +1,55 @@
wn={}
wn.provide=function(namespace){var nsl=namespace.split('.');var l=nsl.length;var parent=window;for(var i=0;i<l;i++){var n=nsl[i];if(!parent[n]){parent[n]={}}
parent=parent[n];}}
wn.provide('wn.settings');wn.provide('wn.ui');wn.xmlhttp={request:function(){if(window.XMLHttpRequest)
return new XMLHttpRequest();else if(window.ActiveXObject)
return new ActiveXObject("MsXml2.XmlHttp");},complete:function(req,callback,url){if(req.status==200||req.status==304){callback(req.responseText);}else{alert(url+' request error: '+req.statusText+' ('+req.status+')');}},get:function(url,callback,async){if(async===null)async=true;var req=wn.xmlhttp.request();req.onreadystatechange=function(){if(req.readyState==4){wn.xmlhttp.complete(req,callback,url)}}
req.open('GET',url,async);req.send(null);if(!async){wn.xmlhttp.complete(req,callback,url)}}}
wn.assets={executed_:{},exists:function(src){if('localStorage'in window&&localStorage.getItem(src)&&localStorage.getItem('[ts] '+src)==asset_timestamps_[src])
return true},add:function(src,txt){if('localStorage'in window){localStorage.setItem(src,txt);localStorage.setItem('[ts] '+src,asset_timestamps_[src]);}},get:function(src){return localStorage.getItem(src);},extn:function(src){return src.split('.').slice(-1)[0];},html_src:function(src){if(src.indexOf('/')!=-1){var t=src.split('/').slice(0,-1);t.push('src');t=t.join('/')+'/'+a.split('/').slice(-1)[0];}else{var t='src/'+src;}
return t;},load:function(src){var t=wn.assets.extn(src)=='html'?wn.assets.html_src(src):src;wn.xmlhttp.get(t,function(txt){wn.assets.add(src,txt);},false)},execute:function(src){if(!wn.assets.exists(src)){wn.assets.load(src);}
var type=wn.assets.extn(src);if(wn.assets.handler[type]){wn.assets.handler[type](wn.assets.get(src),src);wn.assets.executed_[src]=1;}},handler:{js:function(txt,src){wn.dom.eval(txt);},css:function(txt,src){var se=document.createElement('style');se.type="text/css";if(se.styleSheet){se.styleSheet.cssText=txt;}else{se.appendChild(document.createTextNode(txt));}
document.getElementsByTagName('head')[0].appendChild(se);},html:function(txt,src){var page=wn.dom.add($('.outer .inner').get(0),'div','content',null,txt);page.setAttribute("_src",src);}}}
wn.require=function(items){if(typeof items==="string"){items=[items];}
var l=items.length;for(var i=0;i<l;i++){var src=items[i];if(!(src in wn.assets.executed_)){wn.assets.execute(src)}}}
wn.provide('wn.dom');wn.dom.by_id=function(id){return document.getElementById(id);}
wn.dom.eval=function(txt){var el=document.createElement('script');el.appendChild(document.createTextNode(txt));document.getElementsByTagName('head')[0].appendChild(el);}
wn.dom.add=function(parent,newtag,className,cs,innerHTML,onclick){if(parent&&parent.substr)parent=wn.dom.by_id(parent);var c=document.createElement(newtag);if(parent)
parent.appendChild(c);if(className){if(newtag.toLowerCase()=='img')
c.src=className
else
c.className=className;}
if(cs)wn.dom.css(c,cs);if(innerHTML)c.innerHTML=innerHTML;if(onclick)c.onclick=onclick;return c;}
wn.dom.css=function(ele,s){if(ele&&s){for(var i in s)ele.style[i]=s[i];};return ele;}
wn.dom.hide=function(ele){ele.style.display='none';}
wn.dom.show=function(ele,value){if(!value)value='block';ele.style.display=value;}
wn.page={set:function(src){var new_selection=$('.inner div.content[_src="'+src+'"]');if(!new_selection.length){wn.assets.execute(src);new_selection=$('.inner div.content[_src="'+src+'"]');}
$('.inner .current_page').removeClass('current_page');new_selection.addClass('current_page');var title=$('nav ul li a[href*="'+src+'"]').attr('title')||'No Title'
state=History.getState();if(state.hash!=src){History.replaceState(null,title,src);}
else{document.title=title;}}}
var JSON;if(!JSON){JSON={};}
(function(){"use strict";function f(n){return n<10?'0'+n:n;}
if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}
var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}
function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}
if(typeof rep==='function'){value=rep.call(holder,key,value);}
switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}
v=partial.length===0?'[]':gap?'[\n'+gap+partial.join(',\n'+gap)+'\n'+mind+']':'['+partial.join(',')+']';gap=mind;return v;}
if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){if(typeof rep[i]==='string'){k=rep[i];v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}
v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}
rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}
return str('',{'':value});};}
if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}
return reviver.call(holder,key,value);}
text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+
('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}
throw new SyntaxError('JSON.parse');};}}());wn.require("lib/js/lib/jquery.min.js");wn.require("lib/js/lib/history/history.adapter.jquery.js");wn.require("lib/js/lib/history/history.js");wn.require("lib/js/lib/history/history.html4.js");wn.require("lib/js/wn/history.js");$(document).bind('ready',function(){var base=window.location.href.split('#')[0];$.each($('a[softlink!="false"]'),function(i,v){if(v.href.substr(0,base.length)==base){var path=(v.href.substr(base.length));if(path.substr(0,1)!='#'){v.href=base+'#'+path;}}});if(window.location.hash){wn.page.set(window.location.hash.substr(1));}});

68
js/legacy/build.json Normal file
View file

@ -0,0 +1,68 @@
{
"wnf.compressed.js": [
"globals.js"
,"utils/datatype.js"
,"utils/browser_detect.js"
,"utils/datetime.js"
,"utils/dom.js"
,"utils/handler.js"
,"utils/msgprint.js"
,"utils/json.js"
,"utils/shortcut.js"
,"utils/printElement.js"
,"wn/widgets/dialog.js"
,"widgets/dialog.js"
,"widgets/listing.js"
,"wn/widgets/listing.js"
,"widgets/tree.js"
,"widgets/menu.js"
,"widgets/layout.js"
,"widgets/tabbedpage.js"
,"webpage/page_header.js"
,"widgets/autosuggest.js"
,"widgets/select.js"
,"widgets/tags.js"
,"widgets/export_query.js"
,"widgets/list_selector.js"
,"widgets/form/fields.js"
,"webpage/wntoolbar.js"
,"webpage/history.js"
,"webpage/search.js"
,"webpage/spinner.js"
,"webpage/freeze_page.js"
,"webpage/error_console.js"
,"webpage/about.js"
,"webpage/loaders.js"
,"webpage/uploader.js"
,"webpage/page.js"
,"webpage/docbrowser.js"
,"wn/page_layout.js"
,"wn/widgets/page_sidebar.js"
,"wn/widgets/footer.js"
,"model/local_data.js"
,"model/doclist.js"
,"webpage/body.js"
,"app.js"
,"widgets/calendar.js"
],
"form.compressed.js": [
"widgets/form/form_container.js"
,"widgets/form/form_header.js"
,"widgets/form/form.js"
,"widgets/form/form_fields.js"
,"widgets/form/grid.js"
,"widgets/form/form_grid.js"
,"widgets/form/print_format.js"
,"widgets/form/email.js"
,"widgets/form/clientscriptAPI.js"
,"widgets/form/form_comments.js"
,"wn/widgets/form/sidebar.js"
,"wn/widgets/form/comments.js"
,"wn/widgets/form/attachments.js"
],
"report.compressed.js": [
"widgets/report_builder/report_builder.js"
,"widgets/report_builder/datatable.js"
,"widgets/report_builder/calculator.js"
]
}

View file

@ -0,0 +1 @@
(function(a,b){var c=a.History=a.History||{},d=a.jQuery;if(typeof c.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");c.Adapter={bind:function(a,b,c){d(a).bind(b,c)},trigger:function(a,b){d(a).trigger(b)},onDomLoad:function(a){d(a)}},typeof c.init!="undefined"&&c.init()})(window)

View file

@ -0,0 +1 @@
(function(a,b){"use strict";var c=a.document,d=a.setTimeout||d,e=a.clearTimeout||e,f=a.setInterval||f,g=a.History=a.History||{};if(typeof g.initHtml4!="undefined")throw new Error("History.js HTML4 Support has already been loaded...");g.initHtml4=function(){if(typeof g.initHtml4.initialized!="undefined")return!1;g.initHtml4.initialized=!0,g.enabled=!0,g.savedHashes=[],g.isLastHash=function(a){var b=g.getHashByIndex(),c=a===b;return c},g.saveHash=function(a){if(g.isLastHash(a))return!1;g.savedHashes.push(a);return!0},g.getHashByIndex=function(a){var b=null;typeof a=="undefined"?b=g.savedHashes[g.savedHashes.length-1]:a<0?b=g.savedHashes[g.savedHashes.length+a]:b=g.savedHashes[a];return b},g.discardedHashes={},g.discardedStates={},g.discardState=function(a,b,c){var d=g.getHashByState(a),e={discardedState:a,backState:c,forwardState:b};g.discardedStates[d]=e;return!0},g.discardHash=function(a,b,c){var d={discardedHash:a,backState:c,forwardState:b};g.discardedHashes[a]=d;return!0},g.discardedState=function(a){var b=g.getHashByState(a),c=g.discardedStates[b]||!1;return c},g.discardedHash=function(a){var b=g.discardedHashes[a]||!1;return b},g.recycleState=function(a){var b=g.getHashByState(a);g.discardedState(a)&&delete g.discardedStates[b];return!0},g.emulated.hashChange&&(g.hashChangeInit=function(){g.checkerFunction=null;var b="";if(g.isInternetExplorer()){var d="historyjs-iframe",e=c.createElement("iframe");e.setAttribute("id",d),e.style.display="none",c.body.appendChild(e),e.contentWindow.document.open(),e.contentWindow.document.close();var h="",i=!1;g.checkerFunction=function(){if(i)return!1;i=!0;var c=g.getHash()||"",d=g.unescapeHash(e.contentWindow.document.location.hash)||"";c!==b?(b=c,d!==c&&(h=d=c,e.contentWindow.document.open(),e.contentWindow.document.close(),e.contentWindow.document.location.hash=g.escapeHash(c)),g.Adapter.trigger(a,"hashchange")):d!==h&&(h=d,g.setHash(d,!1)),i=!1;return!0}}else g.checkerFunction=function(){var c=g.getHash();c!==b&&(b=c,g.Adapter.trigger(a,"hashchange"));return!0};g.intervalList.push(f(g.checkerFunction,g.options.hashChangeInterval));return!0},g.Adapter.onDomLoad(g.hashChangeInit)),g.emulated.pushState&&(g.onHashChange=function(b){var d=b&&b.newURL||c.location.href,e=g.getHashByUrl(d),f=null,h=null,i=null;if(g.isLastHash(e)){g.busy(!1);return!1}g.doubleCheckComplete(),g.saveHash(e);if(e&&g.isTraditionalAnchor(e)){g.Adapter.trigger(a,"anchorchange"),g.busy(!1);return!1}f=g.extractState(g.getFullUrl(e||c.location.href,!1),!0);if(g.isLastSavedState(f)){g.busy(!1);return!1}h=g.getHashByState(f);var j=g.discardedState(f);if(j){g.getHashByIndex(-2)===g.getHashByState(j.forwardState)?g.back(!1):g.forward(!1);return!1}g.pushState(f.data,f.title,f.url,!1);return!0},g.Adapter.bind(a,"hashchange",g.onHashChange),g.pushState=function(b,d,e,f){if(g.getHashByUrl(e))throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(f!==!1&&g.busy()){g.pushQueue({scope:g,callback:g.pushState,args:arguments,queue:f});return!1}g.busy(!0);var h=g.createStateObject(b,d,e),i=g.getHashByState(h),j=g.getState(!1),k=g.getHashByState(j),l=g.getHash();g.storeState(h),g.expectedStateId=h.id,g.recycleState(h),g.setTitle(h);if(i===k){g.busy(!1);return!1}if(i!==l&&i!==g.getShortUrl(c.location.href)){g.setHash(i,!1);return!1}g.saveState(h),g.Adapter.trigger(a,"statechange"),g.busy(!1);return!0},g.replaceState=function(a,b,c,d){if(g.getHashByUrl(c))throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(d!==!1&&g.busy()){g.pushQueue({scope:g,callback:g.replaceState,args:arguments,queue:d});return!1}g.busy(!0);var e=g.createStateObject(a,b,c),f=g.getState(!1),h=g.getStateByIndex(-2);g.discardState(f,e,h),g.pushState(e.data,e.title,e.url,!1);return!0},g.getHash()&&!g.emulated.hashChange&&g.Adapter.onDomLoad(function(){g.Adapter.trigger(a,"hashchange")}))},g.init()})(window)

File diff suppressed because one or more lines are too long

19
js/lib/history/history.min.js vendored Normal file

File diff suppressed because one or more lines are too long

18
js/lib/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

480
js/lib/json2.js Normal file
View file

@ -0,0 +1,480 @@
/*
http://www.JSON.org/json2.js
2011-02-23
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
See http://www.JSON.org/js.html
This code should be minified before deployment.
See http://javascript.crockford.com/jsmin.html
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
NOT CONTROL.
This file creates a global JSON object containing two methods: stringify
and parse.
JSON.stringify(value, replacer, space)
value any JavaScript value, usually an object or array.
replacer an optional parameter that determines how object
values are stringified for objects. It can be a
function or an array of strings.
space an optional parameter that specifies the indentation
of nested structures. If it is omitted, the text will
be packed without extra whitespace. If it is a number,
it will specify the number of spaces to indent at each
level. If it is a string (such as '\t' or '&nbsp;'),
it contains the characters used to indent at each level.
This method produces a JSON text from a JavaScript value.
When an object value is found, if the object contains a toJSON
method, its toJSON method will be called and the result will be
stringified. A toJSON method does not serialize: it returns the
value represented by the name/value pair that should be serialized,
or undefined if nothing should be serialized. The toJSON method
will be passed the key associated with the value, and this will be
bound to the value
For example, this would serialize Dates as ISO strings.
Date.prototype.toJSON = function (key) {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
You can provide an optional replacer method. It will be passed the
key and value of each member, with this bound to the containing
object. The value that is returned from your method will be
serialized. If your method returns undefined, then the member will
be excluded from the serialization.
If the replacer parameter is an array of strings, then it will be
used to select the members to be serialized. It filters the results
such that only members with keys listed in the replacer array are
stringified.
Values that do not have JSON representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be replaced with null. You can use
a replacer function to replace those with JSON values.
JSON.stringify(undefined) returns undefined.
The optional space parameter produces a stringification of the
value that is filled with line breaks and indentation to make it
easier to read.
If the space parameter is a non-empty string, then that string will
be used for indentation. If the space parameter is a number, then
the indentation will be that many spaces.
Example:
text = JSON.stringify(['e', {pluribus: 'unum'}]);
// text is '["e",{"pluribus":"unum"}]'
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
text = JSON.stringify([new Date()], function (key, value) {
return this[key] instanceof Date ?
'Date(' + this[key] + ')' : value;
});
// text is '["Date(---current time---)"]'
JSON.parse(text, reviver)
This method parses a JSON text to produce an object or array.
It can throw a SyntaxError exception.
The optional reviver parameter is a function that can filter and
transform the results. It receives each of the keys and values,
and its return value is used instead of the original value.
If it returns what it received, then the structure is not modified.
If it returns undefined then the member is deleted.
Example:
// Parse the text. Values that look like ISO date strings will
// be converted to Date objects.
myData = JSON.parse(text, function (key, value) {
var a;
if (typeof value === 'string') {
a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
});
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
var d;
if (typeof value === 'string' &&
value.slice(0, 5) === 'Date(' &&
value.slice(-1) === ')') {
d = new Date(value.slice(5, -1));
if (d) {
return d;
}
}
return value;
});
This is a reference implementation. You are free to copy, modify, or
redistribute.
*/
/*jslint evil: true, strict: false, regexp: false */
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
lastIndex, length, parse, prototype, push, replace, slice, stringify,
test, toJSON, toString, valueOf
*/
// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.
var JSON;
if (!JSON) {
JSON = {};
}
(function () {
"use strict";
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
if (typeof Date.prototype.toJSON !== 'function') {
Date.prototype.toJSON = function (key) {
return isFinite(this.valueOf()) ?
this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z' : null;
};
String.prototype.toJSON =
Number.prototype.toJSON =
Boolean.prototype.toJSON = function (key) {
return this.valueOf();
};
}
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
gap,
indent,
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
rep;
function quote(string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.
escapable.lastIndex = 0;
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string' ? c :
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' : '"' + string + '"';
}
function str(key, holder) {
// Produce a string from holder[key].
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key];
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
// If the type is 'object', we might be dealing with an object or an array or
// null.
case 'object':
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0 ? '[]' : gap ?
'[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
'[' + partial.join(',') + ']';
gap = mind;
return v;
}
// If the replacer is an array, use it to select the members to be stringified.
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
if (typeof rep[i] === 'string') {
k = rep[i];
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0 ? '{}' : gap ?
'{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
'{' + partial.join(',') + '}';
gap = mind;
return v;
}
}
// If the JSON object does not yet have a stringify method, give it one.
if (typeof JSON.stringify !== 'function') {
JSON.stringify = function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.
var i;
gap = '';
indent = '';
// If the space parameter is a number, make an indent string containing that
// many spaces.
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
// If the space parameter is a string, it will be used as the indent string.
} else if (typeof space === 'string') {
indent = space;
}
// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.
return str('', {'': value});
};
}
// If the JSON object does not yet have a parse method, give it one.
if (typeof JSON.parse !== 'function') {
JSON.parse = function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.
var j;
function walk(holder, key) {
// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
text = String(text);
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if (/^[\],:{}\s]*$/
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.
return typeof reviver === 'function' ?
walk({'': j}, '') : j;
}
// If the text is not JSON parseable, then a SyntaxError is thrown.
throw new SyntaxError('JSON.parse');
};
}
}());

View file

@ -0,0 +1,23 @@
/*** adding sf-vertical in addition to sf-menu creates a vertical menu ***/
.sf-vertical, .sf-vertical li {
width: 10em;
}
/* this lacks ul at the start of the selector, so the styles from the main CSS file override it where needed */
.sf-vertical li:hover ul,
.sf-vertical li.sfHover ul {
left: 10em; /* match ul width */
top: 0;
}
/*** alter arrow directions ***/
.sf-vertical .sf-sub-indicator { background-position: -10px 0; } /* IE6 gets solid image only */
.sf-vertical a > .sf-sub-indicator { background-position: 0 0; } /* use translucent arrow for modern browsers*/
/* hover arrow direction for modern browsers*/
.sf-vertical a:focus > .sf-sub-indicator,
.sf-vertical a:hover > .sf-sub-indicator,
.sf-vertical a:active > .sf-sub-indicator,
.sf-vertical li:hover > a > .sf-sub-indicator,
.sf-vertical li.sfHover > a > .sf-sub-indicator {
background-position: -10px 0; /* arrow hovers for modern browsers*/
}

View file

@ -0,0 +1,136 @@
/*** ESSENTIAL STYLES ***/
.sf-menu, .sf-menu * {
margin: 0;
padding: 0;
list-style: none;
}
.sf-menu {
line-height: 1.0;
}
.sf-menu ul {
position: absolute;
top: -999em;
width: 10em; /* left offset of submenus need to match (see below) */
}
.sf-menu ul li {
width: 100%;
}
.sf-menu li:hover {
visibility: inherit; /* fixes IE7 'sticky bug' */
}
.sf-menu li {
float: left;
position: relative;
}
.sf-menu a {
display: block;
position: relative;
}
.sf-menu li:hover ul,
.sf-menu li.sfHover ul {
left: 0;
top: 2.5em; /* match top ul list item height */
z-index: 99;
}
ul.sf-menu li:hover li ul,
ul.sf-menu li.sfHover li ul {
top: -999em;
}
ul.sf-menu li li:hover ul,
ul.sf-menu li li.sfHover ul {
left: 10em; /* match ul width */
top: 0;
}
ul.sf-menu li li:hover li ul,
ul.sf-menu li li.sfHover li ul {
top: -999em;
}
ul.sf-menu li li li:hover ul,
ul.sf-menu li li li.sfHover ul {
left: 10em; /* match ul width */
top: 0;
}
/*** DEMO SKIN ***/
.sf-menu {
float: left;
margin-bottom: 1em;
}
.sf-menu a {
border-left: 1px solid #fff;
border-top: 1px solid #CFDEFF;
padding: .75em 1em;
text-decoration:none;
}
.sf-menu a, .sf-menu a:visited { /* visited pseudo selector so IE6 applies text colour*/
color: #13a;
}
.sf-menu li {
background: #BDD2FF;
}
.sf-menu li li {
background: #AABDE6;
}
.sf-menu li li li {
background: #9AAEDB;
}
.sf-menu li:hover, .sf-menu li.sfHover,
.sf-menu a:focus, .sf-menu a:hover, .sf-menu a:active {
background: #CFDEFF;
outline: 0;
}
/*** arrows **/
.sf-menu a.sf-with-ul {
padding-right: 2.25em;
min-width: 1px; /* trigger IE7 hasLayout so spans position accurately */
}
.sf-sub-indicator {
position: absolute;
display: block;
right: .75em;
top: 1.05em; /* IE6 only */
width: 10px;
height: 10px;
text-indent: -999em;
overflow: hidden;
background: url('assets/js/lib/superfish/images/arrows-ffffff.png') no-repeat -10px -100px; /* 8-bit indexed alpha png. IE6 gets solid image only */
}
a > .sf-sub-indicator { /* give all except IE6 the correct values */
top: .8em;
background-position: 0 -100px; /* use translucent arrow for modern browsers*/
}
/* apply hovers to modern browsers */
a:focus > .sf-sub-indicator,
a:hover > .sf-sub-indicator,
a:active > .sf-sub-indicator,
li:hover > a > .sf-sub-indicator,
li.sfHover > a > .sf-sub-indicator {
background-position: -10px -100px; /* arrow hovers for modern browsers*/
}
/* point right for anchors in subs */
.sf-menu ul .sf-sub-indicator { background-position: -10px 0; }
.sf-menu ul a > .sf-sub-indicator { background-position: 0 0; }
/* apply hovers to modern browsers */
.sf-menu ul a:focus > .sf-sub-indicator,
.sf-menu ul a:hover > .sf-sub-indicator,
.sf-menu ul a:active > .sf-sub-indicator,
.sf-menu ul li:hover > a > .sf-sub-indicator,
.sf-menu ul li.sfHover > a > .sf-sub-indicator {
background-position: -10px 0; /* arrow hovers for modern browsers*/
}
/*** shadows for all but IE6 ***/
.sf-shadow ul {
background: url('assets/js/lib/superfish/images/shadow.png') no-repeat bottom right;
padding: 0 8px 9px 0;
-moz-border-radius-bottomleft: 17px;
-moz-border-radius-topright: 17px;
-webkit-border-top-right-radius: 17px;
-webkit-border-bottom-left-radius: 17px;
}
.sf-shadow ul.sf-shadow-off {
background: transparent;
}

View file

@ -0,0 +1,84 @@
(function($){
/* hoverIntent by Brian Cherne */
$.fn.hoverIntent = function(f,g) {
// default configuration options
var cfg = {
sensitivity: 7,
interval: 100,
timeout: 0
};
// override configuration options with user supplied object
cfg = $.extend(cfg, g ? { over: f, out: g } : f );
// instantiate variables
// cX, cY = current X and Y position of mouse, updated by mousemove event
// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
var cX, cY, pX, pY;
// A private function for getting mouse position
var track = function(ev) {
cX = ev.pageX;
cY = ev.pageY;
};
// A private function for comparing current and previous mouse position
var compare = function(ev,ob) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
// compare mouse positions to see if they've crossed the threshold
if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
$(ob).unbind("mousemove",track);
// set hoverIntent state to true (so mouseOut can be called)
ob.hoverIntent_s = 1;
return cfg.over.apply(ob,[ev]);
} else {
// set previous coordinates for next time
pX = cX; pY = cY;
// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
}
};
// A private function for delaying the mouseOut function
var delay = function(ev,ob) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
ob.hoverIntent_s = 0;
return cfg.out.apply(ob,[ev]);
};
// A private function for handling mouse 'hovering'
var handleHover = function(e) {
// next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } }
if ( p == this ) { return false; }
// copy objects to be passed into t (required for event object to be passed in IE)
var ev = jQuery.extend({},e);
var ob = this;
// cancel hoverIntent timer if it exists
if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }
// else e.type == "onmouseover"
if (e.type == "mouseover") {
// set "previous" X and Y position based on initial entry point
pX = ev.pageX; pY = ev.pageY;
// update "current" X and Y position based on mousemove
$(ob).bind("mousemove",track);
// start polling interval (self-calling timeout) to compare mouse coordinates over time
if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}
// else e.type == "onmouseout"
} else {
// unbind expensive mousemove event
$(ob).unbind("mousemove",track);
// if hoverIntent state is true, then call the mouseOut function after the specified delay
if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
}
};
// bind the function to the two event listeners
return this.mouseover(handleHover).mouseout(handleHover);
};
})(jQuery);

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -0,0 +1,34 @@
// convert to superfish menu
provide('wn.menus.superfish');
wn.menus.superfish = function(parent, data) {
var _make_list = function(myparent, lst) {
var ul = wn.dom.add(myparent, 'ul');
$.each(lst, function(i,v) {
var li = wn.dom.add(ul, 'li')
var a = wn.dom.add(li, 'a', '', '', v.label);
a.action = v.action
// action
if(v.action) {
a.onclick = function() { window[action](); };
}
// link
if(v.href) {
a.href = v.href;
}
// sub menu
if(v.subitems) {
_make_list(li, v.subitems);
}
})
return ul;
}
ul = _make_list(parent, data);
ul.className = 'sf-menu';
// build it
$(ul).superfish();
}

View file

@ -0,0 +1,121 @@
/*
* Superfish v1.4.8 - jQuery menu widget
* Copyright (c) 2008 Joel Birch
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* CHANGELOG: http://users.tpg.com.au/j_birch/plugins/superfish/changelog.txt
*/
;(function($){
$.fn.superfish = function(op){
var sf = $.fn.superfish,
c = sf.c,
$arrow = $(['<span class="',c.arrowClass,'"> &#187;</span>'].join('')),
over = function(){
var $$ = $(this), menu = getMenu($$);
clearTimeout(menu.sfTimer);
$$.showSuperfishUl().siblings().hideSuperfishUl();
},
out = function(){
var $$ = $(this), menu = getMenu($$), o = sf.op;
clearTimeout(menu.sfTimer);
menu.sfTimer=setTimeout(function(){
o.retainPath=($.inArray($$[0],o.$path)>-1);
$$.hideSuperfishUl();
if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);}
},o.delay);
},
getMenu = function($menu){
var menu = $menu.parents(['ul.',c.menuClass,':first'].join(''))[0];
sf.op = sf.o[menu.serial];
return menu;
},
addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); };
return this.each(function() {
var s = this.serial = sf.o.length;
var o = $.extend({},sf.defaults,op);
o.$path = $('li.'+o.pathClass,this).slice(0,o.pathLevels).each(function(){
$(this).addClass([o.hoverClass,c.bcClass].join(' '))
.filter('li:has(ul)').removeClass(o.pathClass);
});
sf.o[s] = sf.op = o;
$('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() {
if (o.autoArrows) addArrow( $('>a:first-child',this) );
})
.not('.'+c.bcClass)
.hideSuperfishUl();
var $a = $('a',this);
$a.each(function(i){
var $li = $a.eq(i).parents('li');
$a.eq(i).focus(function(){over.call($li);}).blur(function(){out.call($li);});
});
o.onInit.call(this);
}).each(function() {
var menuClasses = [c.menuClass];
if (sf.op.dropShadows && !($.browser.msie && $.browser.version < 7)) menuClasses.push(c.shadowClass);
$(this).addClass(menuClasses.join(' '));
});
};
var sf = $.fn.superfish;
sf.o = [];
sf.op = {};
sf.IE7fix = function(){
var o = sf.op;
if ($.browser.msie && $.browser.version > 6 && o.dropShadows && o.animation.opacity!=undefined)
this.toggleClass(sf.c.shadowClass+'-off');
};
sf.c = {
bcClass : 'sf-breadcrumb',
menuClass : 'sf-js-enabled',
anchorClass : 'sf-with-ul',
arrowClass : 'sf-sub-indicator',
shadowClass : 'sf-shadow'
};
sf.defaults = {
hoverClass : 'sfHover',
pathClass : 'overideThisToUse',
pathLevels : 1,
delay : 800,
animation : {opacity:'show'},
speed : 'normal',
autoArrows : true,
dropShadows : true,
disableHI : false, // true disables hoverIntent detection
onInit : function(){}, // callback functions
onBeforeShow: function(){},
onShow : function(){},
onHide : function(){}
};
$.fn.extend({
hideSuperfishUl : function(){
var o = sf.op,
not = (o.retainPath===true) ? o.$path : '';
o.retainPath = false;
var $ul = $(['li.',o.hoverClass].join(''),this).add(this).not(not).removeClass(o.hoverClass)
.find('>ul').hide().css('visibility','hidden');
o.onHide.call($ul);
return this;
},
showSuperfishUl : function(){
var o = sf.op,
sh = sf.c.shadowClass+'-off',
$ul = this.addClass(o.hoverClass)
.find('>ul:hidden').css('visibility','visible');
sf.IE7fix.call($ul);
o.onBeforeShow.call($ul);
$ul.animate(o.animation,o.speed,function(){ sf.IE7fix.call($ul); o.onShow.call($ul); });
return this;
}
});
})(jQuery);

171
js/lib/superfish/superfish.min.js vendored Normal file
View file

@ -0,0 +1,171 @@
(function($){$.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:100,timeout:0};cfg=$.extend(cfg,g?{over:f,out:g}:f);var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY;};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){$(ob).unbind("mousemove",track);ob.hoverIntent_s=1;return cfg.over.apply(ob,[ev]);}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=0;return cfg.out.apply(ob,[ev]);};var handleHover=function(e){var p=(e.type=="mouseover"?e.fromElement:e.toElement)||e.relatedTarget;while(p&&p!=this){try{p=p.parentNode;}catch(e){p=this;}}
if(p==this){return false;}
var ev=jQuery.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);}
if(e.type=="mouseover"){pX=ev.pageX;pY=ev.pageY;$(ob).bind("mousemove",track);if(ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}}else{$(ob).unbind("mousemove",track);if(ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob);},cfg.timeout);}}};return this.mouseover(handleHover).mouseout(handleHover);};})(jQuery);;(function($){$.fn.superfish=function(op){var sf=$.fn.superfish,c=sf.c,$arrow=$(['<span class="',c.arrowClass,'"> &#187;</span>'].join('')),over=function(){var $$=$(this),menu=getMenu($$);clearTimeout(menu.sfTimer);$$.showSuperfishUl().siblings().hideSuperfishUl();},out=function(){var $$=$(this),menu=getMenu($$),o=sf.op;clearTimeout(menu.sfTimer);menu.sfTimer=setTimeout(function(){o.retainPath=($.inArray($$[0],o.$path)>-1);$$.hideSuperfishUl();if(o.$path.length&&$$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);}},o.delay);},getMenu=function($menu){var menu=$menu.parents(['ul.',c.menuClass,':first'].join(''))[0];sf.op=sf.o[menu.serial];return menu;},addArrow=function($a){$a.addClass(c.anchorClass).append($arrow.clone());};return this.each(function(){var s=this.serial=sf.o.length;var o=$.extend({},sf.defaults,op);o.$path=$('li.'+o.pathClass,this).slice(0,o.pathLevels).each(function(){$(this).addClass([o.hoverClass,c.bcClass].join(' ')).filter('li:has(ul)').removeClass(o.pathClass);});sf.o[s]=sf.op=o;$('li:has(ul)',this)[($.fn.hoverIntent&&!o.disableHI)?'hoverIntent':'hover'](over,out).each(function(){if(o.autoArrows)addArrow($('>a:first-child',this));}).not('.'+c.bcClass).hideSuperfishUl();var $a=$('a',this);$a.each(function(i){var $li=$a.eq(i).parents('li');$a.eq(i).focus(function(){over.call($li);}).blur(function(){out.call($li);});});o.onInit.call(this);}).each(function(){var menuClasses=[c.menuClass];if(sf.op.dropShadows&&!($.browser.msie&&$.browser.version<7))menuClasses.push(c.shadowClass);$(this).addClass(menuClasses.join(' '));});};var sf=$.fn.superfish;sf.o=[];sf.op={};sf.IE7fix=function(){var o=sf.op;if($.browser.msie&&$.browser.version>6&&o.dropShadows&&o.animation.opacity!=undefined)
this.toggleClass(sf.c.shadowClass+'-off');};sf.c={bcClass:'sf-breadcrumb',menuClass:'sf-js-enabled',anchorClass:'sf-with-ul',arrowClass:'sf-sub-indicator',shadowClass:'sf-shadow'};sf.defaults={hoverClass:'sfHover',pathClass:'overideThisToUse',pathLevels:1,delay:800,animation:{opacity:'show'},speed:'normal',autoArrows:true,dropShadows:true,disableHI:false,onInit:function(){},onBeforeShow:function(){},onShow:function(){},onHide:function(){}};$.fn.extend({hideSuperfishUl:function(){var o=sf.op,not=(o.retainPath===true)?o.$path:'';o.retainPath=false;var $ul=$(['li.',o.hoverClass].join(''),this).add(this).not(not).removeClass(o.hoverClass).find('>ul').hide().css('visibility','hidden');o.onHide.call($ul);return this;},showSuperfishUl:function(){var o=sf.op,sh=sf.c.shadowClass+'-off',$ul=this.addClass(o.hoverClass).find('>ul:hidden').css('visibility','visible');sf.IE7fix.call($ul);o.onBeforeShow.call($ul);$ul.animate(o.animation,o.speed,function(){sf.IE7fix.call($ul);o.onShow.call($ul);});return this;}});})(jQuery);provide('wn.menus.superfish');wn.menus.superfish=function(parent,data){var _make_list=function(myparent,lst){var ul=wn.dom.add(myparent,'ul');$.each(lst,function(i,v){var li=wn.dom.add(ul,'li')
var a=wn.dom.add(li,'a','','',v.label);a.action=v.action
if(v.action){a.onclick=function(){window[action]();};}
if(v.href){a.href=v.href;}
if(v.subitems){_make_list(li,v.subitems);}})
return ul;}
ul=_make_list(parent,data);ul.className='sf-menu';$(ul).superfish();}
wn.assets.handler.css('\
/*** ESSENTIAL STYLES ***/\
.sf-menu, .sf-menu * {\
margin: 0;\
padding: 0;\
list-style: none;\
}\
.sf-menu {\
line-height: 1.0;\
}\
.sf-menu ul {\
position: absolute;\
top: -999em;\
width: 10em; /* left offset of submenus need to match (see below) */\
}\
.sf-menu ul li {\
width: 100%;\
}\
.sf-menu li:hover {\
visibility: inherit; /* fixes IE7 \'sticky bug\' */\
}\
.sf-menu li {\
float: left;\
position: relative;\
}\
.sf-menu a {\
display: block;\
position: relative;\
}\
.sf-menu li:hover ul,\
.sf-menu li.sfHover ul {\
left: 0;\
top: 2.5em; /* match top ul list item height */\
z-index: 99;\
}\
ul.sf-menu li:hover li ul,\
ul.sf-menu li.sfHover li ul {\
top: -999em;\
}\
ul.sf-menu li li:hover ul,\
ul.sf-menu li li.sfHover ul {\
left: 10em; /* match ul width */\
top: 0;\
}\
ul.sf-menu li li:hover li ul,\
ul.sf-menu li li.sfHover li ul {\
top: -999em;\
}\
ul.sf-menu li li li:hover ul,\
ul.sf-menu li li li.sfHover ul {\
left: 10em; /* match ul width */\
top: 0;\
}\
\
/*** DEMO SKIN ***/\
.sf-menu {\
float: left;\
margin-bottom: 1em;\
}\
.sf-menu a {\
border-left: 1px solid #fff;\
border-top: 1px solid #CFDEFF;\
padding: .75em 1em;\
text-decoration:none;\
}\
.sf-menu a, .sf-menu a:visited { /* visited pseudo selector so IE6 applies text colour*/\
color: #13a;\
}\
.sf-menu li {\
background: #BDD2FF;\
}\
.sf-menu li li {\
background: #AABDE6;\
}\
.sf-menu li li li {\
background: #9AAEDB;\
}\
.sf-menu li:hover, .sf-menu li.sfHover,\
.sf-menu a:focus, .sf-menu a:hover, .sf-menu a:active {\
background: #CFDEFF;\
outline: 0;\
}\
\
/*** arrows **/\
.sf-menu a.sf-with-ul {\
padding-right: 2.25em;\
min-width: 1px; /* trigger IE7 hasLayout so spans position accurately */\
}\
.sf-sub-indicator {\
position: absolute;\
display: block;\
right: .75em;\
top: 1.05em; /* IE6 only */\
width: 10px;\
height: 10px;\
text-indent: -999em;\
overflow: hidden;\
background: url(\'assets/js/lib/superfish/images/arrows-ffffff.png\') no-repeat -10px -100px; /* 8-bit indexed alpha png. IE6 gets solid image only */\
}\
a > .sf-sub-indicator { /* give all except IE6 the correct values */\
top: .8em;\
background-position: 0 -100px; /* use translucent arrow for modern browsers*/\
}\
/* apply hovers to modern browsers */\
a:focus > .sf-sub-indicator,\
a:hover > .sf-sub-indicator,\
a:active > .sf-sub-indicator,\
li:hover > a > .sf-sub-indicator,\
li.sfHover > a > .sf-sub-indicator {\
background-position: -10px -100px; /* arrow hovers for modern browsers*/\
}\
\
/* point right for anchors in subs */\
.sf-menu ul .sf-sub-indicator { background-position: -10px 0; }\
.sf-menu ul a > .sf-sub-indicator { background-position: 0 0; }\
/* apply hovers to modern browsers */\
.sf-menu ul a:focus > .sf-sub-indicator,\
.sf-menu ul a:hover > .sf-sub-indicator,\
.sf-menu ul a:active > .sf-sub-indicator,\
.sf-menu ul li:hover > a > .sf-sub-indicator,\
.sf-menu ul li.sfHover > a > .sf-sub-indicator {\
background-position: -10px 0; /* arrow hovers for modern browsers*/\
}\
\
/*** shadows for all but IE6 ***/\
.sf-shadow ul {\
background: url(\'assets/js/lib/superfish/images/shadow.png\') no-repeat bottom right;\
padding: 0 8px 9px 0;\
-moz-border-radius-bottomleft: 17px;\
-moz-border-radius-topright: 17px;\
-webkit-border-top-right-radius: 17px;\
-webkit-border-bottom-left-radius: 17px;\
}\
.sf-shadow ul.sf-shadow-off {\
background: transparent;\
}\
');wn.assets.handler.css('/*** adding sf-vertical in addition to sf-menu creates a vertical menu ***/\
.sf-vertical, .sf-vertical li {\
width: 10em;\
}\
/* this lacks ul at the start of the selector, so the styles from the main CSS file override it where needed */\
.sf-vertical li:hover ul,\
.sf-vertical li.sfHover ul {\
left: 10em; /* match ul width */\
top: 0;\
}\
\
/*** alter arrow directions ***/\
.sf-vertical .sf-sub-indicator { background-position: -10px 0; } /* IE6 gets solid image only */\
.sf-vertical a > .sf-sub-indicator { background-position: 0 0; } /* use translucent arrow for modern browsers*/\
\
/* hover arrow direction for modern browsers*/\
.sf-vertical a:focus > .sf-sub-indicator,\
.sf-vertical a:hover > .sf-sub-indicator,\
.sf-vertical a:active > .sf-sub-indicator,\
.sf-vertical li:hover > a > .sf-sub-indicator,\
.sf-vertical li.sfHover > a > .sf-sub-indicator {\
background-position: -10px 0; /* arrow hovers for modern browsers*/\
}');

94
js/wn/assets.js Normal file
View file

@ -0,0 +1,94 @@
// library to mange assets (js, css, models, html) etc in the app.
// will try and get from localStorge if latest are available
// or will load them via xmlhttp
// depends on asset_timestamps_ loaded via boot
wn.assets = {
// keep track of executed assets
executed_ : {},
// check if the asset exists in
// localstorage and if the timestamp
// matches with the loaded timestamp
exists: function(src) {
if('localStorage' in window
&& localStorage.getItem(src)
&& localStorage.getItem('[ts] '+src) == asset_timestamps_[src])
return true
},
// add the asset to
// localstorage
add: function(src, txt) {
if('localStorage' in window) {
localStorage.setItem(src, txt);
localStorage.setItem('[ts] ' + src, asset_timestamps_[src]);
}
},
get: function(src) {
return localStorage.getItem(src);
},
extn: function(src) {
return src.split('.').slice(-1)[0];
},
html_src: function(src) {
if(src.indexOf('/')!=-1) {
var t = src.split('/').slice(0,-1);
t.push('src');
t = t.join('/') +'/' + a.split('/').slice(-1)[0];
} else {
var t = 'src/' + src;
}
return t;
},
// load an asset via
// xmlhttp
load: function(src) {
var t = wn.assets.extn(src)=='html' ? wn.assets.html_src(src) : src;
wn.xmlhttp.get(t, function(txt) {
// add it to localstorage
wn.assets.add(src, txt);
}, false)
},
// pass on to the handler to set
execute: function(src) {
if(!wn.assets.exists(src)) {
wn.assets.load(src);
}
var type = wn.assets.extn(src);
if(wn.assets.handler[type]) {
wn.assets.handler[type](wn.assets.get(src), src);
wn.assets.executed_[src] = 1;
}
},
// handle types of assets
// and launch them in the
// app
handler: {
js: function(txt, src) {
wn.dom.eval(txt);
},
css: function(txt, src) {
var se = document.createElement('style');
se.type = "text/css";
if (se.styleSheet) {
se.styleSheet.cssText = txt;
} else {
se.appendChild(document.createTextNode(txt));
}
document.getElementsByTagName('head')[0].appendChild(se);
},
html: function(txt, src) {
// make the html content page
var page = wn.dom.add($('.outer .inner').get(0), 'div', 'content', null, txt);
page.setAttribute("_src", src);
}
}
}

49
js/wn/dom.js Normal file
View file

@ -0,0 +1,49 @@
// add a new dom element
wn.provide('wn.dom');
wn.dom.by_id = function(id) {
return document.getElementById(id);
}
wn.dom.eval = function(txt) {
var el = document.createElement('script');
el.appendChild(document.createTextNode(txt));
// execute the script globally
document.getElementsByTagName('head')[0].appendChild(el);
}
wn.dom.add = function(parent, newtag, className, cs, innerHTML, onclick) {
if(parent && parent.substr)parent = wn.dom.by_id(parent);
var c = document.createElement(newtag);
if(parent)
parent.appendChild(c);
// if image, 3rd parameter is source
if(className) {
if(newtag.toLowerCase()=='img')
c.src = className
else
c.className = className;
}
if(cs) wn.dom.css(c,cs);
if(innerHTML) c.innerHTML = innerHTML;
if(onclick) c.onclick = onclick;
return c;
}
// add css to element
wn.dom.css= function(ele, s) {
if(ele && s) {
for(var i in s) ele.style[i]=s[i];
};
return ele;
}
wn.dom.hide = function(ele) {
ele.style.display = 'none';
}
wn.dom.show = function(ele, value) {
if(!value) value = 'block';
ele.style.display = value;
}

15
js/wn/history.js Normal file
View file

@ -0,0 +1,15 @@
// manage history
// load pages via ajax
// setup the history adapter
// if settings no_history is set, no history will be bound
// this can be used to make it work with legacy
$(document).bind('ready', function() {
if(wn.settings.no_history) return;
History.Adapter.bind(window,'statechange',function() {
var state = History.getState();
// load the state on the browser
wn.page.set(state.hash, state.title);
});
})

28
js/wn/page.js Normal file
View file

@ -0,0 +1,28 @@
wn.page = {
set: function(src) {
var new_selection = $('.inner div.content[_src="'+ src +'"]');
if(!new_selection.length) {
// get from server / localstorage
wn.assets.execute(src);
new_selection = $('.inner div.content[_src="'+ src +'"]');
}
// hide current
$('.inner .current_page').removeClass('current_page');
// show new
new_selection.addClass('current_page');
// get title (the first h1, h2, h3)
var title = $('nav ul li a[href*="' + src + '"]').attr('title') || 'No Title'
// replace state (to url)
state = History.getState();
if(state.hash!=src) {
History.replaceState(null, title, src);
}
else {
document.title = title;
}
}
}

17
js/wn/provide.js Normal file
View file

@ -0,0 +1,17 @@
// provide a namespace
wn = {}
wn.provide = function(namespace) {
var nsl = namespace.split('.');
var l = nsl.length;
var parent = window;
for(var i=0; i<l; i++) {
var n = nsl[i];
if(!parent[n]) {
parent[n] = {}
}
parent = parent[n];
}
}
wn.provide('wn.settings');
wn.provide('wn.ui');

15
js/wn/require.js Normal file
View file

@ -0,0 +1,15 @@
// require js file
wn.require = function(items) {
if(typeof items === "string") {
items = [items];
}
var l = items.length;
for(var i=0; i< l; i++) {
var src = items[i];
if(!(src in wn.assets.executed_)) {
// check if available in localstorage
wn.assets.execute(src)
}
}
}

24
js/wn/ui/overlay.js Normal file
View file

@ -0,0 +1,24 @@
// overlay an element
// http://blog.learnboost.com/blog/a-css3-overlay-system/
wn.ui.Overlay = function(ele) {
wn.require('lib/css/ui/overlay.css');
var me = this;
$.extend(this, {
render: function() {
me.wrap = wn.dom.add(
wn.dom.add(
wn.dom.add($('body').get(0), 'div', 'overlay')
, 'div', 'wrap-outer')
, 'div', 'wrap');
me.wrap.appendChild(ele);
$('body').addClass('overlaid');
},
hide: function() {
wn.dom.hide(me.wrap);
$('body').removeClass('overlaid');
}
});
me.render();
}

22
js/wn/ui/status_bar.js Normal file
View file

@ -0,0 +1,22 @@
wn.ui.StatusBar = function() {
var me = this;
$.extend(this, {
render: function() {
wn.require('lib/js/wn/ui/overlay.js');
wn.require('lib/css/ui/status_bar.css');
me.dialog = wn.dom.add(null, 'div', 'dialog round shadow');
me.outer = wn.dom.add(me.dialog, 'div', 'status_bar_outer');
me.inner = wn.dom.add(me.outer, 'div', 'status_bar_inner');
me.overlay = new wn.ui.Overlay(me.dialog);
},
set_value: function(percent) {
me.inner.style.width = percent + '%';
},
hide: function() {
me.overlay.hide();
}
});
me.render();
}

36
js/wn/xmlhttp.js Normal file
View file

@ -0,0 +1,36 @@
wn.xmlhttp = {
request: function() {
if ( window.XMLHttpRequest ) // Gecko
return new XMLHttpRequest() ;
else if ( window.ActiveXObject ) // IE
return new ActiveXObject("MsXml2.XmlHttp") ;
},
complete: function(req, callback, url) {
if (req.status==200 || req.status==304) {
callback(req.responseText);
} else {
alert(url +' request error: ' + req.statusText + ' (' + req.status + ')' ) ;
}
},
get: function(url, callback, async) {
// async by default
if(async === null) async=true;
var req = wn.xmlhttp.request();
// for async type
req.onreadystatechange = function() {
if (req.readyState==4) {
wn.xmlhttp.complete(req, callback, url)
}
}
req.open('GET', url, async);
req.send(null);
// for sync
if(!async) {
wn.xmlhttp.complete(req, callback, url)
}
}
}

0
py/__init__.py Normal file
View file

21
py/build/__init__.py Normal file
View file

@ -0,0 +1,21 @@
verbose = True
force_rebuild = False
no_minify = False
def run():
"""
Run the builder
"""
global verbose
import sys, os
sys.path.append('py')
sys.path.append('lib/py')
from build.project import Project
verbose = True
Project().build()
if __name__=='__main__':
run()

5
py/build/__main__.py Normal file
View file

@ -0,0 +1,5 @@
if __name__=='__main__':
import sys, os
sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), '..'))
import build
build.run()

142
py/build/bundle.py Normal file
View file

@ -0,0 +1,142 @@
from minify import JavascriptMinify
class Bundle:
"""
Concatenate, compress and mix (if required) js+css files from build.json
"""
def concat(self, filelist, outfile=None, is_js=False):
"""
Concat css and js files into a bundle
"""
import os
from cStringIO import StringIO
from build import verbose
out_type = outfile and outfile.split('.')[-1] or 'js'
temp = StringIO()
for f in filelist:
if verbose:
print f + ' | ' + str(int(os.path.getsize(f)/1024)) + 'k'
fh = open(f)
# get file type
ftype = f.split('.')[-1]
# special concat (css inside js)
if is_js and ftype =='css':
css = fh.read()
data = "\nwn.assets.handler.css('%s');\n" % css.replace("'", "\\'").replace('\n', '\\\n')
# plain concat
else:
data = fh.read() + '\n'
fh.close()
temp.write(data)
if outfile:
f = open(outfile, 'w')
f.write(temp.getvalue())
f.close()
self.timestamps.update(outfile)
if verbose: print 'Wrote %s' % outfile
return temp
def changed(self, files):
"""
Returns true if the files are changed since last build
"""
import os
from build import force_rebuild
if force_rebuild:
return True
for f in files:
if f in self.timestamps.dirty:
return True
return False
def minify(self, in_files, outfile, concat=False):
"""
Compress in_files into outfile,
give some stats
"""
from build import verbose
import os
# concat everything into temp
outtype = outfile.split('.')[-1]
temp = self.concat(in_files, is_js=True)
out = open(outfile, 'w')
org_size = len(temp.getvalue())
temp.seek(0)
# minify
jsm = JavascriptMinify()
jsm.minify(temp, out)
out.close()
self.timestamps.update(outfile)
new_size = os.path.getsize(outfile)
if verbose:
print '=> %s' % outfile
print 'Original: %.2f kB' % (org_size / 1024.0)
print 'Compressed: %.2f kB' % (new_size / 1024.0)
print 'Reduction: %.1f%%' % (float(org_size - new_size) / org_size * 100)
def make(self, path):
"""
Build (stitch + compress) the file defined in build.json
"""
import os, sys, json
from build import no_minify
# open the build.json file and read
# the dict
bfile = open(os.path.join(path, 'build.json'), 'r')
bdata = json.loads(bfile.read())
bfile.close()
for outfile in bdata:
prefix, fname = False, outfile
# check if there is a prefix
if ':' in outfile:
prefix, fname = outfile.split(':')
# build the file list relative to the main folder
fl = [os.path.relpath(os.path.join(path, f), os.curdir) for f in bdata[outfile]]
self.timestamps.bundled += fl
if self.changed(fl):
# js files are minified by default unless explicitly
# mentioned in the prefix.
# some files may not work if minified (known jsmin bug)
if fname.split('.')[-1]=='js' and prefix!='concat' and not no_minify:
self.minify(fl, os.path.relpath(os.path.join(path, fname), os.curdir))
else:
self.concat(fl, os.path.relpath(os.path.join(path, fname), os.curdir))
def bundle(self, timestamps):
"""
Build js files from "build.json"
"""
import os
self.timestamps = timestamps
# walk the parent folder and build all files as defined in the build.json files
for wt in os.walk('.', followlinks=True):
if 'build.json' in wt[2]:
# found build file
self.make(os.path.abspath(wt[0]))

View file

@ -0,0 +1,34 @@
"""
Jinja2 markdown2 extension
by Silas Swell
http://www.silassewell.com/blog/2010/05/10/jinja2-markdown-extension/
"""
import jinja2
import jinja2.ext
import markdown2
class Markdown2Extension(jinja2.ext.Extension):
tags = set(['markdown2'])
def __init__(self, environment):
super(Markdown2Extension, self).__init__(environment)
environment.extend(
markdowner=markdown2.Markdown()
)
def parse(self, parser):
lineno = parser.stream.next().lineno
body = parser.parse_statements(
['name:endmarkdown2'],
drop_needle=True
)
return jinja2.nodes.CallBlock(
self.call_method('_markdown_support'),
[],
[],
body
).set_lineno(lineno)
def _markdown_support(self, caller):
return self.environment.markdowner.convert(caller()).strip()

215
py/build/minify.py Normal file
View file

@ -0,0 +1,215 @@
import os, os.path, shutil
# This code is original from jsmin by Douglas Crockford, it was translated to
# Python by Baruch Even. The original code had the following copyright and
# license.
#
# /* jsmin.c
# 2007-05-22
#
# Copyright (c) 2002 Douglas Crockford (www.crockford.com)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# The Software shall be used for Good, not Evil.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# */
from StringIO import StringIO
def jsmin(js):
ins = StringIO(js)
outs = StringIO()
JavascriptMinify().minify(ins, outs)
str = outs.getvalue()
if len(str) > 0 and str[0] == '\n':
str = str[1:]
return str
def isAlphanum(c):
"""return true if the character is a letter, digit, underscore,
dollar sign, or non-ASCII character.
"""
return ((c >= 'a' and c <= 'z') or (c >= '0' and c <= '9') or
(c >= 'A' and c <= 'Z') or c == '_' or c == '$' or c == '\\' or (c is not None and ord(c) > 126));
class UnterminatedComment(Exception):
pass
class UnterminatedStringLiteral(Exception):
pass
class UnterminatedRegularExpression(Exception):
pass
class JavascriptMinify(object):
def _outA(self):
self.outstream.write(self.theA)
def _outB(self):
self.outstream.write(self.theB)
def _get(self):
"""return the next character from stdin. Watch out for lookahead. If
the character is a control character, translate it to a space or
linefeed.
"""
c = self.theLookahead
self.theLookahead = None
if c == None:
c = self.instream.read(1)
if c >= ' ' or c == '\n':
return c
if c == '': # EOF
return '\000'
if c == '\r':
return '\n'
return ' '
def _peek(self):
self.theLookahead = self._get()
return self.theLookahead
def _next(self):
"""get the next character, excluding comments. peek() is used to see
if an unescaped '/' is followed by a '/' or '*'.
"""
c = self._get()
if c == '/' and self.theA != '\\':
p = self._peek()
if p == '/':
c = self._get()
while c > '\n':
c = self._get()
return c
if p == '*':
c = self._get()
while 1:
c = self._get()
if c == '*':
if self._peek() == '/':
self._get()
return ' '
if c == '\000':
raise UnterminatedComment()
return c
def _action(self, action):
"""do something! What you do is determined by the argument:
1 Output A. Copy B to A. Get the next B.
2 Copy B to A. Get the next B. (Delete A).
3 Get the next B. (Delete B).
action treats a string as a single character. Wow!
action recognizes a regular expression if it is preceded by ( or , or =.
"""
if action <= 1:
self._outA()
if action <= 2:
self.theA = self.theB
if self.theA == "'" or self.theA == '"':
while 1:
self._outA()
self.theA = self._get()
if self.theA == self.theB:
break
if self.theA <= '\n':
raise UnterminatedStringLiteral()
if self.theA == '\\':
self._outA()
self.theA = self._get()
if action <= 3:
self.theB = self._next()
if self.theB == '/' and (self.theA == '(' or self.theA == ',' or
self.theA == '=' or self.theA == ':' or
self.theA == '[' or self.theA == '?' or
self.theA == '!' or self.theA == '&' or
self.theA == '|' or self.theA == ';' or
self.theA == '{' or self.theA == '}' or
self.theA == '\n'):
self._outA()
self._outB()
while 1:
self.theA = self._get()
if self.theA == '/':
break
elif self.theA == '\\':
self._outA()
self.theA = self._get()
elif self.theA <= '\n':
raise UnterminatedRegularExpression()
self._outA()
self.theB = self._next()
def _jsmin(self):
"""Copy the input to the output, deleting the characters which are
insignificant to JavaScript. Comments will be removed. Tabs will be
replaced with spaces. Carriage returns will be replaced with linefeeds.
Most spaces and linefeeds will be removed.
"""
self.theA = '\n'
self._action(3)
while self.theA != '\000':
if self.theA == ' ':
if isAlphanum(self.theB):
self._action(1)
else:
self._action(2)
elif self.theA == '\n':
if self.theB in ['{', '[', '(', '+', '-']:
self._action(1)
elif self.theB == ' ':
self._action(3)
else:
if isAlphanum(self.theB):
self._action(1)
else:
self._action(2)
else:
if self.theB == ' ':
if isAlphanum(self.theA):
self._action(1)
else:
self._action(3)
elif self.theB == '\n':
if self.theA in ['}', ']', ')', '+', '-', '"', '\'']:
self._action(1)
else:
if isAlphanum(self.theA):
self._action(1)
else:
self._action(3)
else:
self._action(1)
def minify(self, instream, outstream):
self.instream = instream
self.outstream = outstream
self.theA = '\n'
self.theB = None
self.theLookahead = None
self._jsmin()
self.instream.close()

67
py/build/nav.py Normal file
View file

@ -0,0 +1,67 @@
class Nav:
"""
Build sitemap / navigation tree
"""
page_info_template = {
'description': None,
'keywords': None,
'title': 'No Title Set'
}
def __init__(self):
"""
write out the nav
"""
import json, os
self.data = {}
if os.path.exists('config/sitenav.json'):
nfile = open('config/sitenav.json')
self.data = json.loads(nfile.read())
nfile.close()
def page_info(self):
"""
return dict with href as the key
"""
ret = {}
import copy
ul = copy.deepcopy(self.data)
for li in ul:
ret[li.get('href')] = li
# has subitems, loop
if li.get('subitems'):
for lia in li.get('subitems'):
if not lia.get('href') in ret.keys():
ul.append(lia)
return ret
def html(self, list_class=''):
"""
return nested lists <ul> in html
"""
self.list_class = list_class
return self.make_list(self.data)
def make_list(self, ul):
"""
return a list with <li> and <a> elements
"""
lis = []
link_html = '<a href="%(href)s" title="%(title)s">%(label)s</a>'
for li in ul:
if not 'title' in li:
li['title'] = 'No Title'
if 'subitems' in li:
h = ('\t<li>' + link_html + self.make_list(li['subitems']) +'</li>') % li
else:
h = ('\t<li>' + link_html + '</li>') % li
lis.append(h)
return '\n<ul class="%s">\n%s\n</ul>' % (self.list_class, '\n'.join(lis))

83
py/build/project.py Normal file
View file

@ -0,0 +1,83 @@
verbose = False
class Project:
"""
Build a project
Make files::
index.html
assets/template.html
assets/js/core.min.js
assets/timestamps.json
"""
def __init__(self,):
"""
load libraries
"""
from build.timestamps import Timestamps
from build.bundle import Bundle
from nav import Nav
self.timestamps = Timestamps()
self.bundle = Bundle()
self.nav = Nav()
def boot(self):
"""
returns bootstrap js
"""
import json
corejs = open('lib/js/core.min.js', 'r')
boot = 'var asset_timestamps_=' + self.timestamps.get('json', ('js', 'html', 'css')) \
+ '\n' + corejs.read()
corejs.close()
return boot
def render_templates(self):
"""
Generate static files from templates
"""
# render templates
import os
from jinja2 import Environment, FileSystemLoader
from build.markdown2_extn import Markdown2Extension
env = Environment(loader=FileSystemLoader('templates'), extensions=[Markdown2Extension])
# dynamic boot info
env.globals['boot'] = self.boot()
env.globals['nav'] = self.nav.html()
page_info = self.nav.page_info()
for wt in os.walk('templates'):
for fname in wt[2]:
if fname.split('.')[-1]=='html' and not fname.startswith('template'):
fpath = os.path.relpath(os.path.join(wt[0], fname), 'templates')
temp = env.get_template(fpath)
env.globals.update(self.nav.page_info_template)
env.globals.update(page_info.get(fpath, {}))
# out file in parent folder of template
f = open(fpath, 'w')
f.write(temp.render())
f.close()
print "Rendered %s | %.2fkb" % (fpath, os.path.getsize(fpath) / 1024.0)
def build(self):
"""
Build all js files, timestamps.js, index.html and template.html
"""
# make bundles
self.bundle.bundle(self.timestamps)
# index, template if framework is dirty
if self.timestamps.dirty:
self.render_templates()
self.timestamps.write()

147
py/build/timestamps.py Normal file
View file

@ -0,0 +1,147 @@
class Timestamps:
"""
Build / manage json timestamp files
"""
previous = {}
dirty = []
bundled = []
current = {}
ignore_hidden = True
ignore_extn = ('pyc', 'DS_Store', 'gitignore')
"""
load timestamps and dirty files
"""
def __init__(self):
self.load()
self.get_current()
self.check_dirty()
def check_dirty(self):
"""
Returns true if the current folder is dirty
"""
from build import verbose
import os
self.dirty = []
if not self.previous:
if verbose:
print 'Dirty: no timestamps!'
self.dirty = self.current.keys()
else:
# check both ways for missing files
for f in self.current:
if self.current[f] != self.previous.get(f):
print '**** %s changed | %s -> %s' % (f, self.previous.get(f), self.current.get(f))
self.dirty.append(f)
for f in self.previous:
if self.previous[f] != self.current.get(f):
if f not in self.dirty:
print '**** %s changed | %s -> %s' % (f, self.previous.get(f), self.current.get(f))
self.dirty.append(f)
# unique
self.dirty = list(set(self.dirty))
def get_current(self):
"""
build timestamps dict for specified files
"""
try:
import config.assets
except ImportError:
return self.get_current_from_folders()
ts = {}
for fname in config.assets.file_list:
ts[fname] = str(int(os.stat(fname).st_mtime))
self.current = ts
def get_current_from_folders(self):
"""
walk in all folders and build tree of all js, css, html, md files
"""
import os
ts = {}
# walk the parent folder and build all files as defined in the build.json files
for wt in os.walk('.', followlinks=True):
# build timestamps
if self.ignore_hidden:
for d in wt[1]:
if d.startswith('.'):
wt[1].remove(d)
if os.path.exists(os.path.join(wt[0], d, '.no_timestamps')):
wt[1].remove(d)
for f in wt[2]:
if f.split('.')[-1] not in self.ignore_extn and f!='_timestamps.js':
fname = os.path.relpath(os.path.join(wt[0], f), os.curdir)
ts[fname] = str(int(os.stat(fname).st_mtime))
self.current = ts
def write(self):
"""
Write timestamp if dirty
"""
import json, os
ts_path = 'config/_timestamps.js'
# write timestamps
f = open(ts_path, 'w')
self.get_current()
f.write(json.dumps(self.current))
f.close()
def load(self):
"""
Get all timestamps from file
"""
from build import verbose
import json, os
ts_path = os.path.join('config', '_timestamps.js')
if os.path.exists(ts_path):
ts = open(ts_path, 'r')
# merge the timestamps
tmp = json.loads(ts.read())
ts.close()
else:
if verbose:
print "** No timestamps **"
tmp = {}
self.previous = tmp
def update(self, fname):
"""
Update timestamp of the given file and add to dirty
"""
import os
self.current[fname] = str(int(os.stat(fname).st_mtime))
self.dirty.append(fname)
def get(self, rettype='dict', types=[]):
"""
return timestamps (ignore the ones not wanted)
"""
# remove all .md timestamps
ret = {}
for t in self.current:
if t.split('.')[-1] in types:
if t not in self.bundled:
ret[t] = self.current[t]
if rettype=='dict':
return ret
else:
import json
return json.dumps(ret)

13
py/common.py Normal file
View file

@ -0,0 +1,13 @@
_store=None
def store():
"""
Return the redis datastore
"""
import redis
global _store
if not _store:
_store = redis.Redis('localhost', port=6379, db=0)
return _store

0
py/core/.no_timestamps Normal file
View file

12
py/tests.py Normal file
View file

@ -0,0 +1,12 @@
import unittest
import urllib, urllib2, os
class TestREST(unittest.TestCase):
def test_home(self):
req = urllib2.Request('http://localhost/rmehta/wnframework-client/')
req.get_method = lambda: 'GET'
response = urllib2.urlopen(req)
self.assertTrue(response.getcode()==200)
if __name__=='__main__':
unittest.main()

11
py/watch.py Normal file
View file

@ -0,0 +1,11 @@
"""
Watch the folder at regular intervals and build if files have been changed
"""
if __name__=='__main__':
import time, build
while 1:
build.run()
time.sleep(2)

View file