Initial shit i think.
This commit is contained in:
commit
e7e0ea4f2a
36
.gitignore
vendored
Normal file
36
.gitignore
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directory
|
||||||
|
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# Bower dependency directory
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
/dump
|
||||||
|
|
||||||
|
/public
|
||||||
|
|
||||||
|
/server/uploads
|
||||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "gulp"]
|
||||||
|
path = gulp
|
||||||
|
url = https://github.com/thecodebureau/gulp.git
|
||||||
1
gulp
Submodule
1
gulp
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 57adc62ecbec966afa0f717e967287c820c09095
|
||||||
12
gulpconfig.js
Normal file
12
gulpconfig.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
module.exports = {
|
||||||
|
browserify: {
|
||||||
|
entries: [
|
||||||
|
'app.js',
|
||||||
|
'admin/app.js'
|
||||||
|
],
|
||||||
|
outputs: [
|
||||||
|
'app.js',
|
||||||
|
'admin.js'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
1
gulpfile.js
Symbolic link
1
gulpfile.js
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
gulp/gulpfile.js
|
||||||
11
nodemon.json
Normal file
11
nodemon.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"ext": "js,dust",
|
||||||
|
"ignore": [
|
||||||
|
"bower_components",
|
||||||
|
"gulp",
|
||||||
|
"node_modules",
|
||||||
|
"public",
|
||||||
|
"samples",
|
||||||
|
"src"
|
||||||
|
]
|
||||||
|
}
|
||||||
16
package.json
Normal file
16
package.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "change-this-fool",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "./server/server.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "The Code Bureau <info@thecodebureau.com> (https://thecodebureau.com)",
|
||||||
|
"dependencies": {
|
||||||
|
"hats": "^0.2.0",
|
||||||
|
"epiphany": "0.6.1",
|
||||||
|
"ridge": "0.5.3",
|
||||||
|
"dustjs-linkedin": "^2.7.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
5
server/config/details.js
Normal file
5
server/config/details.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
title: 'Epiphany',
|
||||||
|
name: 'epiphany'
|
||||||
|
};
|
||||||
|
|
||||||
47
server/config/dir.js
Normal file
47
server/config/dir.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// MODULES
|
||||||
|
|
||||||
|
// modules : NATIVE
|
||||||
|
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
var PWD = process.env.PWD;
|
||||||
|
|
||||||
|
// Server folders. All folder related to the Node server handling most things.
|
||||||
|
module.exports = {
|
||||||
|
// Any code that needs to a "middle landing spot" while built, place it anywhere here
|
||||||
|
build: {
|
||||||
|
root: path.join(PWD, 'build')
|
||||||
|
},
|
||||||
|
|
||||||
|
// public directories. Where all static/built/live content goes.
|
||||||
|
public: {
|
||||||
|
css: path.join(PWD, 'public', 'css'),
|
||||||
|
fonts: path.join(PWD, 'public', 'fonts'),
|
||||||
|
img: path.join(PWD, 'public', 'img'),
|
||||||
|
root: path.join(PWD, 'public'),
|
||||||
|
scripts: path.join(PWD, 'public', 'js')
|
||||||
|
},
|
||||||
|
|
||||||
|
root: PWD,
|
||||||
|
|
||||||
|
server: {
|
||||||
|
middleware: path.join(PWD, 'server', 'middleware'),
|
||||||
|
models: path.join(PWD, 'server', 'models'),
|
||||||
|
routes: path.join(PWD, 'server', 'routes'),
|
||||||
|
root: path.join(PWD, 'server'),
|
||||||
|
schemas: path.join(PWD, 'server', 'schema.org'),
|
||||||
|
templates: path.join(PWD, 'server', 'templates'),
|
||||||
|
uploads: path.join(PWD, 'server', 'uploads')
|
||||||
|
},
|
||||||
|
|
||||||
|
// Source directories. This is where you put all content that needs to be built before use.
|
||||||
|
src: {
|
||||||
|
fonts: path.join(PWD, 'src', 'fonts'),
|
||||||
|
raster: path.join(PWD, 'src', 'raster'),
|
||||||
|
root: path.join(PWD, 'src'),
|
||||||
|
sass: path.join(PWD, 'src', 'sass'),
|
||||||
|
static: path.join(PWD, 'src', 'static'),
|
||||||
|
scripts: path.join(PWD, 'src', 'js'),
|
||||||
|
svg: path.join(PWD, 'src', 'svg'),
|
||||||
|
}
|
||||||
|
};
|
||||||
12
server/config/domain.js
Normal file
12
server/config/domain.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
module.exports = function(config) {
|
||||||
|
if(!config.port || !_.isNumber(config.port)) throw new Error('Port undefined or not a number');
|
||||||
|
|
||||||
|
return {
|
||||||
|
development: 'localhost:' + config.port,
|
||||||
|
testing: 'changeThisFool.testing.thecodebureau.com',
|
||||||
|
staging: 'changeThisFool.thecodebureau.com',
|
||||||
|
production: 'www.changeThisFool.se'
|
||||||
|
}[ENV];
|
||||||
|
};
|
||||||
23
server/config/error-handler.js
Normal file
23
server/config/error-handler.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
module.exports = {
|
||||||
|
defaults: {
|
||||||
|
mystify: {
|
||||||
|
properties: [ 'message', 'name', 'status', 'statusText' ]
|
||||||
|
},
|
||||||
|
log: {
|
||||||
|
// if database = true there has to be a mongoose model name ErrorModel
|
||||||
|
ignore: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
development: {
|
||||||
|
log: {
|
||||||
|
database: false,
|
||||||
|
console: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
production: {
|
||||||
|
log: {
|
||||||
|
database: true,
|
||||||
|
console: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
10
server/config/globals.js
Normal file
10
server/config/globals.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
module.exports = function(bind) {
|
||||||
|
bind = bind || global;
|
||||||
|
|
||||||
|
bind.ENV = process.env.NODE_ENV || 'development';
|
||||||
|
bind.PWD = process.env.PWD;
|
||||||
|
//bind.LOGIN_USER = 'username';
|
||||||
|
//bind.LOGIN_USER = 'email@domain.com';
|
||||||
|
};
|
||||||
10
server/config/mongo.js
Normal file
10
server/config/mongo.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module.exports = {
|
||||||
|
defaults: {
|
||||||
|
uri: 'mongodb://localhost/changeThisFool'
|
||||||
|
//uri: 'mongodb://user:password@tcb01.thecodebureau.com/changeThisFool'
|
||||||
|
},
|
||||||
|
development: {
|
||||||
|
//uri: 'mongodb://user:password@tcb01.thecodebureau.com/changeThisFoolDev'
|
||||||
|
uri: 'mongodb://localhost/changeThisFoolDev'
|
||||||
|
}
|
||||||
|
};
|
||||||
8
server/config/port.js
Normal file
8
server/config/port.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
var basePort = 10000;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
development: basePort,
|
||||||
|
testing: basePort + 1,
|
||||||
|
staging: basePort + 2,
|
||||||
|
production: basePort + 3
|
||||||
|
}[ENV];
|
||||||
14
server/config/session.js
Normal file
14
server/config/session.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
module.exports = {
|
||||||
|
defaults: {
|
||||||
|
secret: 'changeThisFool',
|
||||||
|
resave: true,
|
||||||
|
saveUninitialized: true
|
||||||
|
},
|
||||||
|
production: {
|
||||||
|
redis: {
|
||||||
|
port: 6379,
|
||||||
|
host: 'localhost'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
13
server/modules.js
Normal file
13
server/modules.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
module.exports = [
|
||||||
|
// hats > hats
|
||||||
|
//'hats/base',
|
||||||
|
//'hats/admin',
|
||||||
|
//'hats/errors',
|
||||||
|
//'hats/organization',
|
||||||
|
//'hats/news',
|
||||||
|
//'hats/gallery',
|
||||||
|
//'hats/employees',
|
||||||
|
|
||||||
|
// hats > project
|
||||||
|
//'./hats/events',
|
||||||
|
];
|
||||||
30
server/pages.js
Normal file
30
server/pages.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
module.exports = function(mw) {
|
||||||
|
return {
|
||||||
|
public: [
|
||||||
|
{
|
||||||
|
title: 'Start',
|
||||||
|
template: 'pages/index',
|
||||||
|
path: '/'
|
||||||
|
}, {
|
||||||
|
title: 'Spytext'
|
||||||
|
}, {
|
||||||
|
title: 'Playground'
|
||||||
|
}, {
|
||||||
|
title: 'CSS',
|
||||||
|
name: 'css'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
//redirects: [
|
||||||
|
// [ '/coupon','/kupongen' ],
|
||||||
|
//],
|
||||||
|
|
||||||
|
//admin: [
|
||||||
|
// {
|
||||||
|
// title: 'Dashboard',
|
||||||
|
// path: '/',
|
||||||
|
// template: 'admin/pages/index'
|
||||||
|
// }
|
||||||
|
//]
|
||||||
|
};
|
||||||
|
};
|
||||||
9
server/server.js
Normal file
9
server/server.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
var Epiphany = require('epiphany');
|
||||||
|
|
||||||
|
var server = new Epiphany({
|
||||||
|
modules: require('./modules'),
|
||||||
|
pages: require('./pages'),
|
||||||
|
start: false
|
||||||
|
});
|
||||||
|
|
||||||
|
server.start();
|
||||||
9
server/templates/error.dust
Normal file
9
server/templates/error.dust
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<div class="error page row">
|
||||||
|
<div class="col">
|
||||||
|
<h1>Oops!</h1>
|
||||||
|
<p>Ett problem har tyvärr uppstått.<p>
|
||||||
|
<h2>{error.status} : {error.statusText}</h2>
|
||||||
|
<p>{error.message}<p>
|
||||||
|
<pre>{error.stack}</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
62
server/templates/master.dust
Normal file
62
server/templates/master.dust
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>TCB IT & Development AB</title>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
|
||||||
|
<link rel="shortcut icon" href="/favicon.png" />
|
||||||
|
|
||||||
|
<link type="text/css" rel="stylesheet" href="/css/main.css" />
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="company">
|
||||||
|
<h1 class="logo"><span>TCB IT & Development</span></h1>
|
||||||
|
</div>
|
||||||
|
{>"partials/navigation":navigation page=page /}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
|
||||||
|
{?error}
|
||||||
|
{>"error"/}
|
||||||
|
{:else}
|
||||||
|
{?template}
|
||||||
|
{>"{template}"/}
|
||||||
|
{/template}
|
||||||
|
{/error}
|
||||||
|
|
||||||
|
</main>
|
||||||
|
<footer class="bottom">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col m-6">Copyright TCB IT & Development AB</div>
|
||||||
|
<div class="col m-6 text-right">Website by <a href="https://thecodebureau.com">TCB</a>.</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.1/backbone-min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.13.1/jquery.validate.min.js"></script>
|
||||||
|
|
||||||
|
<!-- IE Fixes -->
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/selectivizr/1.0.2/selectivizr-min.js"></script>
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
|
||||||
|
<!--[if lt IE 10]>
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-placeholder/2.0.8/jquery.placeholder.min.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
|
||||||
|
<script src="/js/common.js"></script>
|
||||||
|
<script src="/js/app.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
23
server/templates/pages/css.dust
Normal file
23
server/templates/pages/css.dust
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<div class="css page row">
|
||||||
|
<div class="col">
|
||||||
|
<h1>CSS playground</h1>
|
||||||
|
<div class="container">
|
||||||
|
<div>One</div>
|
||||||
|
<div>Two</div>
|
||||||
|
<div>Three</div>
|
||||||
|
<div>Four</div>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<div>One</div>
|
||||||
|
<div>Two</div>
|
||||||
|
<div>Three</div>
|
||||||
|
<div>Four</div>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<div>One</div>
|
||||||
|
<div>Two</div>
|
||||||
|
<div>Three</div>
|
||||||
|
<div>Four</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
26
server/templates/pages/d3.dust
Normal file
26
server/templates/pages/d3.dust
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<div class="css page row">
|
||||||
|
<div class="col">
|
||||||
|
<h1>D3 Testing Area</h1>
|
||||||
|
|
||||||
|
<div class="D3">
|
||||||
|
<div class="container">
|
||||||
|
<div>One</div>
|
||||||
|
<div>Two</div>
|
||||||
|
<div>Three</div>
|
||||||
|
<div>Four</div>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<div>One</div>
|
||||||
|
<div>Two</div>
|
||||||
|
<div>Three</div>
|
||||||
|
<div>Four</div>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<div>One</div>
|
||||||
|
<div>Two</div>
|
||||||
|
<div>Three</div>
|
||||||
|
<div>Four</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
95
server/templates/pages/index.dust
Normal file
95
server/templates/pages/index.dust
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<div class="page row">
|
||||||
|
<section data-title="Welcome" class="welcome">
|
||||||
|
<header class="col">
|
||||||
|
<h1>Welcome / Välkommen!</h1>
|
||||||
|
<h2><span>The Code Bureau:</span> Advanced Web Development & Design</h2>
|
||||||
|
</header>
|
||||||
|
<div class="col m-6">
|
||||||
|
<p>The Code Bureau is a web development & design firm based in Lund,
|
||||||
|
Sweden. Unlike most other web designers/developers, all our employees
|
||||||
|
have a background in mathematics or computer science.</p>
|
||||||
|
<p class="emph">We make it our business to stay up to date on the latest
|
||||||
|
trends and technologies. The applications we create are always
|
||||||
|
state-of-the-art and built for the future. When you employ us, you wont need to update your
|
||||||
|
products for years.</p>
|
||||||
|
</div>
|
||||||
|
<div class="col m-6">
|
||||||
|
<p>We cater a range of different services to our customers;
|
||||||
|
always focusing on the development of code for the web. Our love for code
|
||||||
|
and the new possibilities of the web enable us to do almost anything. Just ask.</p>
|
||||||
|
<p class="emph">The Code Bureau is a fairly new venture, and as such we
|
||||||
|
are still building a portfolio of show cases. During this time we
|
||||||
|
are offering our services at greatly reduced prices.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section data-title="What We Do" class="what-we-do">
|
||||||
|
<header class="col">
|
||||||
|
<h1>What We Do</h1>
|
||||||
|
</header>
|
||||||
|
<div class="item col m-4">
|
||||||
|
<h2><span>Web Pages</span></h2>
|
||||||
|
<p>Obviously we create websites. Essentially everything we create are
|
||||||
|
web sites of varying complexity. However, we refer to web sites as our
|
||||||
|
entry level products that mainly focus on presentation of information without excessive functionality.</p>
|
||||||
|
</div>
|
||||||
|
<div class="item col m-4">
|
||||||
|
<h2><span>Web Apps</span></h2>
|
||||||
|
<p>Web apps are advanced web sites that emulate functionality usually
|
||||||
|
found in native apps or programs.</p>
|
||||||
|
|
||||||
|
<p>Web apps have, unlike native apps, the benefit of running on all
|
||||||
|
computers and devices. The users only need a browser to access its
|
||||||
|
functionality.</p>
|
||||||
|
</div>
|
||||||
|
<div class="item col m-4">
|
||||||
|
<h2><span>Web Games</span></h2>
|
||||||
|
<p>As the name suggests, web games are games made to run in a browser on any device.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section data-title="Why Choose Us" class="why-choose-us">
|
||||||
|
<header class="col">
|
||||||
|
<h1>Why Choose Us?</h1>
|
||||||
|
</header>
|
||||||
|
<div class="col">
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
<h2>We know code</h2>
|
||||||
|
<p>Most web designers or developers are artistically creative individuals. However,
|
||||||
|
to create stable, reliable web sites and apps you need to know more than design. We
|
||||||
|
are a collection of individuals that both truly love and know code, computers and the web.</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<h2>SEO</h2>
|
||||||
|
<p>Search Engine Optimization is probably the most important
|
||||||
|
factor for a web sites success. It is also constantly changing, and your web sites
|
||||||
|
need to be updated constantly to stay ahead of the competition.</p>
|
||||||
|
<p>One of the most important factors for good SEO today is the speed
|
||||||
|
of your website. Using a framework like WordPress will doom you to a
|
||||||
|
slow web site with poor search engine performance. Our web sites
|
||||||
|
are many, many times faster than those built with WordPress or similar.</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<h2>Future Proof</h2>
|
||||||
|
<p>The internet and web browsers have become infinately more advanced the last few years. Web sites are quickly becoming
|
||||||
|
more like apps and the user experience can be greatly improved. Our love for code means we understand the trends, and can
|
||||||
|
make decisions that ensure our products will be up to date for years to come. No WordPress or PHP here.</p>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section data-title="Contact" class="contact">
|
||||||
|
<header class="col">
|
||||||
|
<h1>Contact</h1>
|
||||||
|
</header>
|
||||||
|
<div typeof="Organization" class="col">
|
||||||
|
<p property="telephone" class="phone">+46 (0) 708 922 122</p>
|
||||||
|
<p property="email" class="email"><a href="mailto:info@thecodebureau.com">info@thecodebureau.com</a></p>
|
||||||
|
<p class="address"><span property="legalName">TCB IT & Development AB</span><br />
|
||||||
|
Ideon Agora<br />
|
||||||
|
<span typeof="PostalAddress" property="address">
|
||||||
|
<span property="streetAddress">Scheelevägen 15</span><br />
|
||||||
|
<span property="postalCode">22363</span> <span property="addressLocality">Lund</span><br />
|
||||||
|
<span property="addressCountry">Sweden</span></p>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
20
server/templates/pages/mod.dust
Normal file
20
server/templates/pages/mod.dust
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<div class="mod page row">
|
||||||
|
<div class="col">
|
||||||
|
<h1>MOD</h1>
|
||||||
|
|
||||||
|
<div class="mod">
|
||||||
|
<div class="container">
|
||||||
|
<div>One</div>
|
||||||
|
<div>Two</div>
|
||||||
|
<div>Three</div>
|
||||||
|
<div>Four</div>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<div>One</div>
|
||||||
|
<div>Two</div>
|
||||||
|
<div>Three</div>
|
||||||
|
<div>Four</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
9
server/templates/pages/playground.dust
Normal file
9
server/templates/pages/playground.dust
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<div class="page row">
|
||||||
|
<div class="col" data-view="TreeWalker">
|
||||||
|
<h1>Playground</h1>
|
||||||
|
<div id="tree-walker" contentEditable=true><p>aaa<u><b>bbb</b><i>ccc</i>ddd<b>eee</b><strike>fff<strong>ggg</strong></strike></u>hhh<b id="start">456</b></p><p><br/></p><p><br/></p><p><br/></p><p>aaa</p></div>
|
||||||
|
<div id="walker" contentEditable=true><script>var a = 4</script><style>body { background: white !important; }</style><p>aaa<u><b>bbb</b><i>ccc</i>ddd<b>eee</b><strike>fff<strong>ggg</strong></strike></u>hhh<b id="start">456</b></p><p><br/></p><p><br/></p><p><br/></p><p>aaa</p></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
128
server/templates/pages/spytext.dust
Normal file
128
server/templates/pages/spytext.dust
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
<div class="spytext page row">
|
||||||
|
<div class="col">
|
||||||
|
<h1>Spytext</h1>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col m-6">
|
||||||
|
<div data-view="SpytextField">
|
||||||
|
<p>AAA<b><u>BBB</u></b>CCC</p>
|
||||||
|
<p>DDD<br><br></p>
|
||||||
|
<p>EEE<b><u>FFF</u></b>GGG</p>
|
||||||
|
<p>HHH<b>III<u>KKK</u>LLL</b>MMM</p>
|
||||||
|
<ul>
|
||||||
|
<li>NNN</li>
|
||||||
|
<li><br></li>
|
||||||
|
<li>OOO</li>
|
||||||
|
</ul>
|
||||||
|
<p>PPP</p>
|
||||||
|
<ul>
|
||||||
|
<li>RRR</li>
|
||||||
|
<li>SSS</li>
|
||||||
|
<li>TTT</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col m-6">
|
||||||
|
<div data-view="SpytextField">
|
||||||
|
<p>One lorem ipsum dolor sit amet, <b><u>consectetur adipiscing elit. Maecenas semper</u></b> turpis eros, sed rhoncus purus sodales sit amet.</p>
|
||||||
|
<p>Two quisque lacus est, B TWO this is some bold molestie et diam id, varius sagittis nisi. Donec placerat mi egestas, congue ligula non, lacinia tortor.<br><br></p>
|
||||||
|
<p>Three aecenas <b><u>B U THREE laskjdf</u></b> id sodales dui. Nulla ipsum justo, elementum in fermentum at, feugiat nec neque.</p>
|
||||||
|
<p>Four vestibulum <b>B tempor <u>U dolor vitae</u> risus</b> faucibus elementum. Aliquam leo odio, convallis non luctus eu, faucibus vel lorem.</p>
|
||||||
|
<ul>
|
||||||
|
<li>Top Menu Item 1</li>
|
||||||
|
<li>Top Menu Item 2</li>
|
||||||
|
<li>Top Menu Item 3</li>
|
||||||
|
<li>Top Menu Item 4</li>
|
||||||
|
<li>Top Menu Item 5</li>
|
||||||
|
</ul>
|
||||||
|
<p>Paragraph 1<br><br></p>
|
||||||
|
<p>Para<br>graph 2</p>
|
||||||
|
<p>Paragraph 3<br><div></div></p>
|
||||||
|
<p>Paragraph 4</p>
|
||||||
|
<p>Paragraph 5</p>
|
||||||
|
<p>Paragraph 6</p>
|
||||||
|
<ul>
|
||||||
|
<li>Middle Menu Item 1</li>
|
||||||
|
<li>Middle Menu Item 2</li>
|
||||||
|
<li>Middle Menu Item 3</li>
|
||||||
|
<li>Middle Menu Item 4</li>
|
||||||
|
<li>Middle Menu Item 5</li>
|
||||||
|
</ul>
|
||||||
|
<p>Paragraph 1</p>
|
||||||
|
<p>Paragraph 2</p>
|
||||||
|
<p>Paragraph 3</p>
|
||||||
|
<p>Paragraph 4</p>
|
||||||
|
<p>Paragraph 5</p>
|
||||||
|
<p>Paragraph 6</p>
|
||||||
|
<ul>
|
||||||
|
<li>Bottom Menu Item 1</li>
|
||||||
|
<li>Bottom Menu Item 2</li>
|
||||||
|
<li>Bottom Menu Item 3</li>
|
||||||
|
<li>Bottom Menu Item 4</li>
|
||||||
|
<li>Bottom Menu Item 5</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col m-6">
|
||||||
|
<div data-view="SpytextField">
|
||||||
|
<p>One lorem ipsum dolor sit amet, <b><u>consectetur adipiscing elit. Maecenas semper</u></b> turpis eros, sed rhoncus purus sodales sit amet.</p>
|
||||||
|
<p>Two quisque lacus est, B TWO this is some bold molestie et diam id, varius sagittis nisi. Donec placerat mi egestas, congue ligula non, lacinia tortor.<br><br></p>
|
||||||
|
<p>Three aecenas <b><u>B U THREE laskjdf</u></b> id sodales dui. Nulla ipsum justo, elementum in fermentum at, feugiat nec neque.</p>
|
||||||
|
<p>Four vestibulum <b>B tempor <u>U dolor vitae</u> risus</b> faucibus elementum. Aliquam leo odio, convallis non luctus eu, faucibus vel lorem.</p>
|
||||||
|
<ul>
|
||||||
|
<li>test</li>
|
||||||
|
<li><br></li>
|
||||||
|
<li>test</li>
|
||||||
|
</ul>
|
||||||
|
<p>Test</p>
|
||||||
|
<ul>
|
||||||
|
<li>test</li>
|
||||||
|
<li>test</li>
|
||||||
|
<li>test</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col m-6">
|
||||||
|
<div data-view="SpytextField">
|
||||||
|
<h1>Hello</h1>
|
||||||
|
<ul>
|
||||||
|
<li>List Item 1</li>
|
||||||
|
<li>List Item 2</li>
|
||||||
|
<li>List Item 3</li>
|
||||||
|
<li>Sublist
|
||||||
|
<ul>
|
||||||
|
<li>Sublist Item 1</li>
|
||||||
|
<li>Sublist Item 2</li>
|
||||||
|
<li>Sublist Item 3</li>
|
||||||
|
<li>Sublist
|
||||||
|
<ul>
|
||||||
|
<li>Sublist Item 1</li>
|
||||||
|
<li>Sublist Item 2</li>
|
||||||
|
<li>Sublist Item 3</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>Test 1</p>
|
||||||
|
<p>Test 2</p>
|
||||||
|
<p>Test 3</p>
|
||||||
|
<p>Test 4</p>
|
||||||
|
<p>Test 5</p>
|
||||||
|
<p>Test 6</p>
|
||||||
|
<p>Test 7</p>
|
||||||
|
<ul>
|
||||||
|
<li>test</li>
|
||||||
|
<li><br></li>
|
||||||
|
<li>test</li>
|
||||||
|
</ul>
|
||||||
|
<p>Test</p>
|
||||||
|
<ul>
|
||||||
|
<li>test</li>
|
||||||
|
<li>test</li>
|
||||||
|
<li>test</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
332
server/templates/spytext-toolbar.bak.dust
Normal file
332
server/templates/spytext-toolbar.bak.dust
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
module.exports = function() {
|
||||||
|
events: {
|
||||||
|
'click button': 'command'
|
||||||
|
},
|
||||||
|
|
||||||
|
template: 'spytext-toolbar',
|
||||||
|
|
||||||
|
command: function() {
|
||||||
|
var command = $(e.currentTarget).attr('data-command');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var SpytextButton = function(config, spytext) {
|
||||||
|
this.spytext = spytext;
|
||||||
|
this.config = typeof config.preset === 'string' ? merge(this.presets[config.preset], config) : config;
|
||||||
|
this.element = $('<button class="spytext-button" st-button-type="' + config.preset + '" tabindex="' + -1 + '">')[0];
|
||||||
|
|
||||||
|
for(var property in this.events)
|
||||||
|
$(this.element).on(property, this.events[property].bind(this));
|
||||||
|
|
||||||
|
this.disable();
|
||||||
|
};
|
||||||
|
|
||||||
|
SpytextButton.prototype = {
|
||||||
|
setActive: function() {
|
||||||
|
$(this.element).addClass('active');
|
||||||
|
},
|
||||||
|
|
||||||
|
unsetActive: function() {
|
||||||
|
$(this.element).removeClass('active');
|
||||||
|
},
|
||||||
|
|
||||||
|
enable: function() {
|
||||||
|
this.element.disabled = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
disable: function() {
|
||||||
|
this.element.disabled = true;
|
||||||
|
this.unsetActive();
|
||||||
|
},
|
||||||
|
|
||||||
|
events: {
|
||||||
|
click: function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.spytext.execute(this.config.action, this.config.options);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
presets: {
|
||||||
|
alignLeft: { title: 'Align Left', action: 'align', options: { alignment: 'left' }},
|
||||||
|
alignRight: { title: 'Align Right', action: 'align', options: { alignment: 'right' }},
|
||||||
|
alignCenter: { title: 'Align Center', action: 'align', options: { alignment: 'center' }},
|
||||||
|
alignJustify: { title: 'Align Justify', action: 'align', options: { alignment: 'justify' }},
|
||||||
|
bold: { title: 'Bold', action: 'format', options: { tag: 'B' }},
|
||||||
|
strikeThrough: { title: 'Strike Through', action: 'format', options: { tag: 'STRIKE' }},
|
||||||
|
underline: { title: 'Underline', action: 'format', options: { tag: 'U' }},
|
||||||
|
italic: { title: 'Italic', action: 'format', options: { tag: 'I' }},
|
||||||
|
removeFormat: { action: 'removeFormat' },
|
||||||
|
typeHeading1: { title: 'Heading 1', action: 'block', options: { tag: 'H1' }},
|
||||||
|
typeHeading2: { title: 'Heading 2', action: 'block', options: { tag: 'H2' }},
|
||||||
|
typeHeading3: { title: 'Heading 3', action: 'block', options: { tag: 'H3' }},
|
||||||
|
typeHeading4: { title: 'Heading 4', action: 'block', options: { tag: 'H4' }},
|
||||||
|
typeHeading5: { title: 'Heading 5', action: 'block', options: { tag: 'H5' }},
|
||||||
|
typeHeading6: { title: 'Heading 6', action: 'block', options: { tag: 'H6' }},
|
||||||
|
typeParagraph: { title: 'Paragraph', action: 'block', options: { tag: 'P' }},
|
||||||
|
orderedList: { title: 'Ordered List', action: 'list', options: { tag: 'OL' }},
|
||||||
|
unorderedList: { title: 'Unordered List', action: 'list', options: { tag: 'UL' }},
|
||||||
|
indent: { title: 'Indent', action: 'indent', options: { outdent: false }},
|
||||||
|
outdent: { title: 'Outdent', action: 'indent', options: { outdent: true }}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var SpytextDropdown = function(config, spytext) {
|
||||||
|
this.spytext = spytext;
|
||||||
|
this.config = typeof config.preset === 'string' ? merge(this.presets[config.preset], config) : config;
|
||||||
|
this.items = [];
|
||||||
|
this.element = $('<ul class="spytext-dropdown">')[0];
|
||||||
|
|
||||||
|
var property;
|
||||||
|
|
||||||
|
this.config.items.forEach(function(item) {
|
||||||
|
var $el = $('<li><span>' + item.title + '</span></li>');
|
||||||
|
$(this.element).append($el);
|
||||||
|
|
||||||
|
for(property in this.events.item)
|
||||||
|
$el.on(property, this.events.item[property].bind(this));
|
||||||
|
|
||||||
|
this.items.push(item);
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
for(property in this.events.dropdown)
|
||||||
|
$(this.element).on(property, this.events.dropdown[property].bind(this));
|
||||||
|
|
||||||
|
this.index = 0;
|
||||||
|
this.length = $(this.element).children().length;
|
||||||
|
this.disable();
|
||||||
|
};
|
||||||
|
|
||||||
|
SpytextDropdown.prototype = {
|
||||||
|
setIndex: function(index) {
|
||||||
|
this.index = index;
|
||||||
|
var liHeight = this.element.children[0].offsetHeight;
|
||||||
|
var children = this.element.children;
|
||||||
|
|
||||||
|
for(var i = 0; i < children.length; i++) {
|
||||||
|
$(children[i]).css('top', '-' + (index * liHeight) + 'px');
|
||||||
|
|
||||||
|
if(i === index) $(children[i]).addClass('active');
|
||||||
|
else $(children[i]).removeClass('active');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setNoActive: function() {
|
||||||
|
this.index = 0;
|
||||||
|
var children = this.element.children;
|
||||||
|
|
||||||
|
for(var i = 0; i < children.length; i++) {
|
||||||
|
$(children[i]).css('top', '0');
|
||||||
|
$(children[i]).removeClass('active');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setActive: function(options) {
|
||||||
|
for(var i = 0; i < this.items.length; i++)
|
||||||
|
for(var prop in options)
|
||||||
|
if(options[prop] === this.items[i].options[prop])
|
||||||
|
return this.setIndex(i);
|
||||||
|
},
|
||||||
|
|
||||||
|
enable: function() {
|
||||||
|
$(this.element).removeClass('disabled');
|
||||||
|
},
|
||||||
|
|
||||||
|
disable: function() {
|
||||||
|
$(this.element).addClass('disabled').removeClass('expanded');
|
||||||
|
this.setNoActive();
|
||||||
|
},
|
||||||
|
|
||||||
|
events: {
|
||||||
|
dropdown: {
|
||||||
|
click: function(e) {
|
||||||
|
if(this.spytext.currentField) {
|
||||||
|
$(this.element).toggleClass('expanded');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
item: {
|
||||||
|
click: function(e) {
|
||||||
|
if($(this.element).hasClass('expanded')) {
|
||||||
|
var index = $(this.element).children().index(e.currentTarget);
|
||||||
|
this.spytext.execute(this.config.action, this.items[index].options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
presets: {
|
||||||
|
type: {
|
||||||
|
action: 'block',
|
||||||
|
items: [
|
||||||
|
{ title: 'Heading 1', options: { tag: 'H1' }},
|
||||||
|
{ title: 'Heading 2', options: { tag: 'H2' }},
|
||||||
|
{ title: 'Heading 3', options: { tag: 'H3' }},
|
||||||
|
{ title: 'Heading 4', options: { tag: 'H4' }},
|
||||||
|
{ title: 'Heading 5', options: { tag: 'H5' }},
|
||||||
|
{ title: 'Heading 6', options: { tag: 'H6' }},
|
||||||
|
{ title: 'Paragraph', options: { tag: 'P' }}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var SpytextToolbar = function(config, spytext) {
|
||||||
|
this.dropdowns = [];
|
||||||
|
this.buttons = [];
|
||||||
|
this.spytext = spytext;
|
||||||
|
this.config = typeof config.preset === 'string' ? merge(this.presets[config.preset], config) : config;
|
||||||
|
this.element = $('<div class="spytext-toolbar">')[0];
|
||||||
|
|
||||||
|
for(var property in this.config.dropdowns)
|
||||||
|
this.addDropdown.call(this, this.config.dropdowns[property], property);
|
||||||
|
|
||||||
|
for(property in this.config.buttonGroups)
|
||||||
|
this.addButtonGroup.call(this, this.config.buttonGroups[property], property);
|
||||||
|
|
||||||
|
for(property in this.events)
|
||||||
|
$(this.element).on(property, this.events[property].bind(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
SpytextToolbar.prototype = {
|
||||||
|
addButtonGroup: function(group) {
|
||||||
|
var $ul = $('<UL>').addClass('spytext-button-group ' + group.name);
|
||||||
|
group.buttons.forEach(function(buttonType) {
|
||||||
|
var $li = $('<LI>');
|
||||||
|
var button = this.addButton({ preset: buttonType }, this.spytext);
|
||||||
|
$ul.append($li);
|
||||||
|
$li.append(button.element);
|
||||||
|
}.bind(this));
|
||||||
|
$(this.element).append($ul);
|
||||||
|
},
|
||||||
|
|
||||||
|
addButton: function(config) {
|
||||||
|
var button = new SpytextButton(config, this.spytext);
|
||||||
|
this.buttons[config.preset] = button;
|
||||||
|
return button;
|
||||||
|
},
|
||||||
|
|
||||||
|
addDropdown: function(config) {
|
||||||
|
config = typeof config === 'string' ? { preset: config } : config;
|
||||||
|
var dropdown = new SpytextDropdown(config, this.spytext);
|
||||||
|
this.dropdowns[config.preset] = dropdown;
|
||||||
|
$(this.element).append(dropdown.element);
|
||||||
|
return dropdown;
|
||||||
|
},
|
||||||
|
|
||||||
|
enable: function() {
|
||||||
|
for(var i in this.buttons) {
|
||||||
|
var button = this.buttons[i];
|
||||||
|
//button.element.setAttribute('disabled');
|
||||||
|
button.enable();
|
||||||
|
}
|
||||||
|
for(var j in this.dropdowns) {
|
||||||
|
this.dropdowns[j].enable();
|
||||||
|
//button.element.setAttribute('disabled');
|
||||||
|
}
|
||||||
|
$(this.element).addClass('active');
|
||||||
|
},
|
||||||
|
|
||||||
|
disable: function() {
|
||||||
|
for(var i in this.buttons) {
|
||||||
|
this.buttons[i].disable();
|
||||||
|
}
|
||||||
|
for(var j in this.dropdowns) {
|
||||||
|
this.dropdowns[j].disable();
|
||||||
|
}
|
||||||
|
$(this.element).removeClass('active');
|
||||||
|
},
|
||||||
|
|
||||||
|
setActiveStyles: function() {
|
||||||
|
function setBlock(tag) {
|
||||||
|
switch(tag) {
|
||||||
|
case 'P':
|
||||||
|
case 'H1':
|
||||||
|
case 'H2':
|
||||||
|
case 'H3':
|
||||||
|
case 'H4':
|
||||||
|
case 'H5':
|
||||||
|
case 'H6':
|
||||||
|
if(that.dropdowns.type) {
|
||||||
|
that.dropdowns.type.setActive({ tag: tag });
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'UL':
|
||||||
|
that.buttons.unorderedList.setActive();
|
||||||
|
that.dropdowns.type.setNoActive();
|
||||||
|
break;
|
||||||
|
case 'OL':
|
||||||
|
that.buttons.orderedList.setActive();
|
||||||
|
that.dropdowns.type.setNoActive();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var that = this;
|
||||||
|
var tags = [];
|
||||||
|
var blocks = [];
|
||||||
|
var rng;
|
||||||
|
var s = 0;
|
||||||
|
|
||||||
|
while(!rng) {
|
||||||
|
rng = this.spytext.currentField.selectron.range();
|
||||||
|
if(s++ > 10000) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!rng) return;
|
||||||
|
|
||||||
|
if(rng.collapsed) {
|
||||||
|
tags = ancestors(rng.startContainer, null, this.spytext.currentField.element);
|
||||||
|
|
||||||
|
// The last element should always be the block element, such as P or UL.
|
||||||
|
} else {
|
||||||
|
var el = rng.commonAncestorContainer;
|
||||||
|
tags = ancestors(el, null, this.spytext.element);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tags.length > 0) blocks.push(tags.pop());
|
||||||
|
|
||||||
|
for(var i in this.buttons) {
|
||||||
|
var button = this.buttons[i];
|
||||||
|
if(button.config.options && $(tags).is(button.config.options.tag).length > 0) {
|
||||||
|
button.setActive();
|
||||||
|
} else button.unsetActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
var blockTag;
|
||||||
|
for(var j = 0; j < blocks.length; j++) {
|
||||||
|
if(blockTag && blockTag !== blocks[j].tagName) {
|
||||||
|
blockTag = null;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
blockTag = blocks[j].tagName || null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(blockTag) setBlock(blockTag);
|
||||||
|
},
|
||||||
|
|
||||||
|
presets: {
|
||||||
|
standard: {
|
||||||
|
dropdowns: [ 'type' ],
|
||||||
|
buttonGroups: [
|
||||||
|
//{ name: 'block', buttons: ['typeHeading1', 'typeHeading2', 'typeHeading3', 'typeHeading4', 'typeHeading5', 'typeHeading6', 'typeParagraph']},
|
||||||
|
{ name: 'format', buttons: ['bold', 'italic', 'underline', 'strikeThrough', 'removeFormat']},
|
||||||
|
{ name: 'align', buttons: ['alignLeft', 'alignCenter', 'alignRight', 'alignJustify']},
|
||||||
|
{ name: 'list', buttons: ['unorderedList', 'orderedList']},
|
||||||
|
{ name: 'indent', buttons: ['indent', 'outdent']}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
format: {
|
||||||
|
buttonGroups: [
|
||||||
|
{ name: 'format', buttons: ['bold', 'underline', 'strikeThrough', 'removeFormat']},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
events: {
|
||||||
|
mousedown: function(e) {
|
||||||
|
// this is needed to prevent toolbar from stealing focus
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
72
server/templates/spytext-toolbar.dust
Normal file
72
server/templates/spytext-toolbar.dust
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<div class="spytext-toolbar">
|
||||||
|
<ul class="spytext-dropdown">
|
||||||
|
<li style="top: 0px;">
|
||||||
|
<button data-command="block" data-option="h1">Heading 1</button>
|
||||||
|
</li>
|
||||||
|
<li style="top: 0px;">
|
||||||
|
<button data-command="block" data-option="h2">Heading 2</button>
|
||||||
|
</li>
|
||||||
|
<li style="top: 0px;">
|
||||||
|
<button data-command="block" data-option="h3">Heading 3</button>
|
||||||
|
</li>
|
||||||
|
<li style="top: 0px;">
|
||||||
|
<button data-command="block" data-option="h4">Heading 4</button>
|
||||||
|
</li>
|
||||||
|
<li style="top: 0px;">
|
||||||
|
<button data-command="block" data-option="h5">Heading 5</button>
|
||||||
|
</li>
|
||||||
|
<li style="top: 0px;">
|
||||||
|
<button data-command="block" data-option="h6">Heading 6</button>
|
||||||
|
</li>
|
||||||
|
<li style="top: 0px;">
|
||||||
|
<button data-command="block" data-option="p">Paragraph</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="spytext-button-group format">
|
||||||
|
<li>
|
||||||
|
<button class="spytext-button bold" data-command="format" data-option="strong" tabindex="-1"></button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="spytext-button italic" data-command="format" data-option="em" tabindex="-1"></button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="spytext-button underline" data-command="format" data-option="u" tabindex="-1"></button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="spytext-button strike-through" data-command="format" data-option="strike" tabindex="-1"></button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="spytext-button remove-format" data-command="format" tabindex="-1"></button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="spytext-button-group align">
|
||||||
|
<li>
|
||||||
|
<button class="spytext-button align-left" data-command="align" data-option="left" tabindex="-1"></button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="spytext-button align-center" data-command="align" data-option="center" tabindex="-1"></button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="spytext-button align-right" data-command="align" data-option="right" tabindex="-1"></button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="spytext-button align-justify" data-command="align" data-option="justify" tabindex="-1"></button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="spytext-button-group list">
|
||||||
|
<li>
|
||||||
|
<button class="spytext-button unordered-list" data-command="list" data-option="ul" tabindex="-1"></button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="spytext-button ordered-list" data-command="list" data-option="ol" tabindex="-1"></button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="spytext-button-group indent">
|
||||||
|
<li>
|
||||||
|
<button class="spytext-button indent" data-command="indent" tabindex="-1"></button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button class="spytext-button outdent" data-command="outdent" tabindex="-1"></button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
32
src/js/admin/app.js
Normal file
32
src/js/admin/app.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
var Ridge = require('ridge');
|
||||||
|
|
||||||
|
var app = new Ridge({
|
||||||
|
router: {
|
||||||
|
root: '/admin'
|
||||||
|
},
|
||||||
|
templateRoot: 'admin/',
|
||||||
|
models: require('../models'),
|
||||||
|
collections: require('../collections'),
|
||||||
|
views: require('./views'),
|
||||||
|
modules: [
|
||||||
|
// hats > native
|
||||||
|
//require('hats/admin'),
|
||||||
|
//require('hats/organization/admin'),
|
||||||
|
//require('hats/errors/admin'),
|
||||||
|
//require('hats/news/admin'),
|
||||||
|
//require('hats/gallery/admin'),
|
||||||
|
//require('hats/employees/admin'),
|
||||||
|
|
||||||
|
// hats > project
|
||||||
|
//require('../../../hats/events/admin'),
|
||||||
|
//require('../../../hats/sponsors/admin')
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
window.broadcast = _.extend({}, Backbone.Events);
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
app.navigation = new app.views.Navigation({ el: app.$('nav') });
|
||||||
|
|
||||||
|
Backbone.history.start({ silent: true, pushState: true });
|
||||||
|
});
|
||||||
6
src/js/admin/views/index.js
Normal file
6
src/js/admin/views/index.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
Page: require('ridge/views/page'),
|
||||||
|
Model: require('ridge/views/model'),
|
||||||
|
Collection: require('ridge/views/collection'),
|
||||||
|
Navigation: require('./navigation')
|
||||||
|
};
|
||||||
22
src/js/admin/views/navigation.js
Normal file
22
src/js/admin/views/navigation.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
module.exports = {
|
||||||
|
initialize: function() {
|
||||||
|
this.listenTo(this.app.router, 'route', this.onRouteChange);
|
||||||
|
},
|
||||||
|
|
||||||
|
onRouteChange: function(route, params) {
|
||||||
|
this.$('li.current').removeClass('current');
|
||||||
|
|
||||||
|
var path = (params[0] || 'dashboard').split('/');
|
||||||
|
|
||||||
|
var $ref = this.$el.children('ul');
|
||||||
|
|
||||||
|
while($ref.length > 0 && path.length > 0) {
|
||||||
|
var $el = $ref.children('.' + path.shift());
|
||||||
|
|
||||||
|
$el.addClass('current');
|
||||||
|
|
||||||
|
$ref = $el.children('ul');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
16
src/js/app.js
Normal file
16
src/js/app.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
var Ridge = require('ridge');
|
||||||
|
|
||||||
|
var app = new Ridge({
|
||||||
|
collections: require('./collections'),
|
||||||
|
models: require('./models'),
|
||||||
|
views: require('./views')
|
||||||
|
});
|
||||||
|
|
||||||
|
app.module(require('spytext'));
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
app.navigation = new app.views.Navigation({ el: app.$('nav') });
|
||||||
|
|
||||||
|
Backbone.history.start({ silent: true, pushState: true });
|
||||||
|
});
|
||||||
|
|
||||||
2
src/js/collections/index.js
Normal file
2
src/js/collections/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
module.exports = {
|
||||||
|
};
|
||||||
2
src/js/models/index.js
Normal file
2
src/js/models/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
module.exports = {
|
||||||
|
};
|
||||||
6
src/js/views/index.js
Normal file
6
src/js/views/index.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
Page: require('ridge/views/page'),
|
||||||
|
Message: require('ridge/views/message'),
|
||||||
|
Navigation: require('./navigation'),
|
||||||
|
TreeWalker: require('./tree-walker')
|
||||||
|
};
|
||||||
53
src/js/views/navigation.js
Normal file
53
src/js/views/navigation.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
module.exports = {
|
||||||
|
events: {
|
||||||
|
'mouseover ul': 'dud',
|
||||||
|
'mouseout ul': 'dud',
|
||||||
|
'click i, div.cover, ul': 'toggleMobile',
|
||||||
|
},
|
||||||
|
|
||||||
|
toggleMobile: function(e) {
|
||||||
|
if(document.body.clientWidth < 640) {
|
||||||
|
this.$('ul').toggleClass('show').on('touchmove', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
$(document.body).toggleClass('push');
|
||||||
|
// breaks iOS:
|
||||||
|
this.$('div.cover').toggleClass('active');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
dud: function() {
|
||||||
|
var $element = this.$('li:hover'),
|
||||||
|
left, width;
|
||||||
|
|
||||||
|
if($element.length === 0)
|
||||||
|
$element = this.$('li.current');
|
||||||
|
|
||||||
|
this.$el.children('.dud').toggleClass('active', $element.length !== 0).css({
|
||||||
|
left: $element.length === 0 ? '' : $element[0].offsetLeft + 'px',
|
||||||
|
width: $element.length === 0 ? 0 : $element.width() + 'px'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function(options) {
|
||||||
|
this.listenTo(this.app.router, 'route', this.onRouteChange);
|
||||||
|
},
|
||||||
|
|
||||||
|
attach: function() {
|
||||||
|
// wait for fonts to load
|
||||||
|
setTimeout(this.dud.bind(this), 300);
|
||||||
|
},
|
||||||
|
|
||||||
|
onRouteChange: function(route, params) {
|
||||||
|
$(document.body).removeClass('push');
|
||||||
|
|
||||||
|
var path = params[0];
|
||||||
|
|
||||||
|
path = path ? path.split('/')[0] : 'index';
|
||||||
|
|
||||||
|
this.$('li.current').removeClass('current');
|
||||||
|
this.$('li.' + path).addClass('current');
|
||||||
|
|
||||||
|
this.dud();
|
||||||
|
}
|
||||||
|
};
|
||||||
18
src/js/views/spytext.js
Normal file
18
src/js/views/spytext.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
var Spytext = require('spytext');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
events: {
|
||||||
|
},
|
||||||
|
|
||||||
|
attach: function() {
|
||||||
|
var _view = this;
|
||||||
|
|
||||||
|
_view.$('[data-spytext]').each(function(i, el) {
|
||||||
|
// TODO clear previous spytext fields
|
||||||
|
if(!_view.spytext) _view.spytext = new Spytext();
|
||||||
|
|
||||||
|
_view.spytext.addField(el);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
53
src/js/views/tree-walker.js
Normal file
53
src/js/views/tree-walker.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
var s = window.getSelection;
|
||||||
|
var selectron = require('spytext/selectron');
|
||||||
|
|
||||||
|
function offsetold(node, value, root) {
|
||||||
|
value = value || 0;
|
||||||
|
root = root || document.body;
|
||||||
|
|
||||||
|
var tw = document.createTreeWalker(root);
|
||||||
|
var last = tw.currentNode = node;
|
||||||
|
|
||||||
|
while(tw.previousNode() !== tw.root) {
|
||||||
|
//!getComputedStyle(node).display.match(/inline/);
|
||||||
|
var nodeType = tw.currentNode.nodeType;
|
||||||
|
if(nodeType === 1 && (
|
||||||
|
last.nodeType === 1 && last === tw.currentNode.nextSibling ||
|
||||||
|
last.nodeType === 3 && last === tw.currentNode.firstChild
|
||||||
|
) ||
|
||||||
|
nodeType === 3 && last !== tw.currentNode.nextSibling)
|
||||||
|
value++;
|
||||||
|
|
||||||
|
if(tw.currentNode.nodeType === 3) {
|
||||||
|
value += tw.currentNode.textContent.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log(tw.currentNode);
|
||||||
|
//console.log('value: ' + value);
|
||||||
|
last = tw.currentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
attach: function() {
|
||||||
|
console.log('attach');
|
||||||
|
var $root = this.$('#tree-walker');
|
||||||
|
$root.on('keydown', function(e) {
|
||||||
|
if (e.ctrlKey && e.keyCode === 65) {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log(selectron.getOffset($root[0]));
|
||||||
|
//console.log(selectron.restore($root[0], selectron.getOffset($root[0]) + 1));
|
||||||
|
var positions = selectron.get($root[0]);
|
||||||
|
s().removeAllRanges();
|
||||||
|
setTimeout(function() {
|
||||||
|
selectron.set(positions);
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
20
src/sass/_content.scss
Normal file
20
src/sass/_content.scss
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
/* --------- MOD ------------------ */
|
||||||
|
|
||||||
|
div.mod {
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 300px;
|
||||||
|
> div {
|
||||||
|
float: left;
|
||||||
|
width: 25%;
|
||||||
|
min-height: 200px;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
form.spytext {
|
||||||
|
.spytext-field {
|
||||||
|
min-height: 300px;
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/sass/_layout.scss
Normal file
41
src/sass/_layout.scss
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
nav {
|
||||||
|
> ul {
|
||||||
|
@include wipe-list;
|
||||||
|
> li {
|
||||||
|
padding: 0 10px;
|
||||||
|
float: left;
|
||||||
|
&:first-child { padding-left: 0; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: scroll;
|
||||||
|
> main {
|
||||||
|
overflow-x: hidden;
|
||||||
|
width: 100%;
|
||||||
|
max-width: $row-max-width;
|
||||||
|
margin: 0 auto;
|
||||||
|
> .page {
|
||||||
|
width: 100%;
|
||||||
|
&.animate {
|
||||||
|
transition: opacity 0.2s ease-out;
|
||||||
|
float: left;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
&.leave {
|
||||||
|
margin-right: -100%;
|
||||||
|
}
|
||||||
|
&.leave.active {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
&.enter {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
&.enter.active, &.leave {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
78
src/sass/_variables_spysass.scss
Normal file
78
src/sass/_variables_spysass.scss
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// required for rem() and em() to work in this file
|
||||||
|
@import "spysass/functions";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Base
|
||||||
|
//
|
||||||
|
|
||||||
|
//$include-reset: true;
|
||||||
|
//$include-normalize: false;
|
||||||
|
|
||||||
|
//$make-image-inline-block: false;
|
||||||
|
//$default-float: left;
|
||||||
|
//$opposite-direction: right;
|
||||||
|
//$text-direction: left;
|
||||||
|
//$global-radius: 0;
|
||||||
|
//$make-image-inline-block: false;
|
||||||
|
|
||||||
|
//$color-main-1: #0066c6;
|
||||||
|
//$color-message: #333;
|
||||||
|
//$color-error: #c90000;
|
||||||
|
//$color-success: #628b1c;
|
||||||
|
|
||||||
|
// This needs to be a px value since rem and em-calc use it. It is translated
|
||||||
|
// to a percante unit for html and body font-sizing like so: strip-unit($base-font-size) / 16 * 100%;
|
||||||
|
//$base-font-size: 16px;
|
||||||
|
//$base-line-height: 1.6;
|
||||||
|
//$base-line-height-computed: $base-line-height * 1rem;
|
||||||
|
|
||||||
|
//$body-font-color: #222;
|
||||||
|
//$body-font-family: "Times New Roman", sans-serif;
|
||||||
|
//$body-font-weight: normal;
|
||||||
|
//$body-font-style: normal;
|
||||||
|
//$body-bg: #fff;
|
||||||
|
|
||||||
|
//$font-smoothing: subpixel-antialiased;
|
||||||
|
|
||||||
|
// Need to be in pixels for IE8
|
||||||
|
//$small-range: 0px, 639px;
|
||||||
|
//$medium-range: 640px, 1023px;
|
||||||
|
//$large-range: 1024px, 1439px;
|
||||||
|
//$xlarge-range: 1440px, 1920px;
|
||||||
|
//$xxlarge-range: 1921px, 999999px;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Grid
|
||||||
|
//
|
||||||
|
|
||||||
|
//$column-gutter: rem(30);
|
||||||
|
//$row-width: rem(1000);
|
||||||
|
//$total-columns: 12;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Type
|
||||||
|
//
|
||||||
|
|
||||||
|
//$heading-font-family: $body-font-family;
|
||||||
|
//$heading-font-weight: bold;
|
||||||
|
//$heading-font-style: normal;
|
||||||
|
//$heading-font-color: $body-font-color;
|
||||||
|
//$heading-text-rendering: optimizeLegibility;
|
||||||
|
//$heading-top-margin: $base-line-height-computed;
|
||||||
|
//$heading-bottom-margin: $base-line-height-computed / 2;
|
||||||
|
//$heading-line-height: 1.2;
|
||||||
|
|
||||||
|
//$h1-font-size: 2.5rem;//40px when base-font-size is 16px
|
||||||
|
//$h2-font-size: 2.0rem;//32px when base-font-size is 16px
|
||||||
|
//$h3-font-size: 1.7rem;//27.2px when base-font-size is 16px
|
||||||
|
//$h4-font-size: 1.4rem;//22.4px when base-font-size is 16px
|
||||||
|
//$h5-font-size: 1.2rem;//19.2px when base-font-size is 16px
|
||||||
|
//$h6-font-size: 1.0rem;
|
||||||
|
|
||||||
|
//$paragraph-font-family: $body-font-family;
|
||||||
|
//$paragraph-font-weight: normal;
|
||||||
|
//$paragraph-font-size: 1.0rem;
|
||||||
|
//$paragraph-line-height: $base-line-height;
|
||||||
|
//$paragraph-margin: 0 0 ($base-line-height-computed / 2);
|
||||||
|
//$paragraph-text-rendering: optimizeLegibility;
|
||||||
|
|
||||||
2
src/sass/admin/main.scss
Normal file
2
src/sass/admin/main.scss
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@import 'spysass';
|
||||||
|
@import 'themes/admin/one';
|
||||||
15
src/sass/main.scss
Normal file
15
src/sass/main.scss
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
@import "spysass";
|
||||||
|
|
||||||
|
@import "components/type";
|
||||||
|
@import "components/grid";
|
||||||
|
|
||||||
|
@import "themes/spytext/niknus";
|
||||||
|
@import "themes/form/foundation";
|
||||||
|
|
||||||
|
@import "layout";
|
||||||
|
@import "content";
|
||||||
|
|
||||||
|
#tree-walker {
|
||||||
|
padding: 15px;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
3
src/static/robots.txt
Normal file
3
src/static/robots.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
User-agent: *
|
||||||
|
Disallow: /admin/
|
||||||
|
Disallow: /api/
|
||||||
Loading…
Reference in New Issue
Block a user