From 5547758e91509da949d5e93e51a70e322aefde92 Mon Sep 17 00:00:00 2001 From: chee Date: Fri, 29 Nov 2013 11:41:18 +0000 Subject: [PATCH] stickers zomg --- .dir-locals.el | 2 + app.js | 112 +++++++ data/icons.json | 1 + package.json | 19 +- public/components/icon_editor.hjs | 12 + public/index.html | 0 public/javascripts/hogan.js | 500 ++++++++++++++++++++++++++++++ public/javascripts/javascript.js | 96 ++++++ public/javascripts/main.js | 20 ++ public/old.html | 230 ++++++++++++++ public/stylesheets/style.css | 88 ++++++ public/stylesheets/style.styl | 90 ++++++ routes/index.js | 15 + routes/user.js | 8 + views/index.hjs | 32 ++ 15 files changed, 1218 insertions(+), 7 deletions(-) create mode 100644 .dir-locals.el create mode 100644 app.js create mode 100644 data/icons.json create mode 100644 public/components/icon_editor.hjs create mode 100644 public/index.html create mode 100644 public/javascripts/hogan.js create mode 100644 public/javascripts/javascript.js create mode 100644 public/javascripts/main.js create mode 100644 public/old.html create mode 100644 public/stylesheets/style.css create mode 100644 public/stylesheets/style.styl create mode 100644 routes/index.js create mode 100644 routes/user.js create mode 100644 views/index.hjs diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000..9ec8f9d --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,2 @@ +((nil . ((indent-tabs-mode . t) + (tab-width . 4)))) diff --git a/app.js b/app.js new file mode 100644 index 0000000..6b67137 --- /dev/null +++ b/app.js @@ -0,0 +1,112 @@ +/** + * Module dependencies. + */ + +var express = require('express'); +var routes = require('./routes'); +var user = require('./routes/user'); +var http = require('http'); +var path = require('path'); +var fs = require('fs'); +var app = express(); +var websockServer = require('websocket').server; + +// all environments +app.set('port', process.env.PORT || 48813); +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'hjs'); +app.use(express.favicon()); +app.use(express.logger('dev')); +app.use(express.json()); +app.use(express.urlencoded()); +app.use(express.methodOverride()); +app.use(app.router); +app.use(require('stylus').middleware(path.join(__dirname, 'public'))); +app.use(express.static(path.join(__dirname, 'public'))); + +// development only +if ('development' == app.get('env')) { + app.use(express.errorHandler()); +} + +app.get('/', routes.index); +app.get('/users', user.list); + +var web = http.createServer(app).listen(app.get('port'), function(){ + console.log('Express server listening on port ' + app.get('port')); +}); + +// websocks +var socket = new websockServer({ + httpServer: web, + autoAcceptConnections: false +}); + +function originIsAllowed(origin) { + console.log(origin); + return 'lol'; +} + +connections = []; + +socket.on('request', function(request) { + if (!originIsAllowed(request.origin)) { + request.reject(); + console.log('hello, i rejected' + request.origin); + return; + } + + var connection = (function() { + try { + return request.accept('wow', request.origin); + } catch (error) { + return; + } + }()); + + if (!connection) return; + console.log('i accept', request.origin); + connections.push(connection); + connection.on('close', function() { + connections.forEach(function (cached, index) { + if (cached == connection) { + delete connections[index]; + } + }); + }); + + connection.on('message', function (message) { + message = (function() { + try { + return JSON.parse(message.utf8Data); + } catch (error) { + return; + } + }()); + + if (!message) return; + connections.forEach(function(cached) { + cached.send(JSON.stringify(message)); + }); + + fs.readFile('data/icons.json', function (up, buffer) { + if (up) throw up; + try { + var stickers = JSON.parse(buffer.toString()); + + stickers.forEach(function (sticker, index) { + if (sticker.id == message.id) { + stickers[index] = message; + } + }); + + fs.writeFile('data/icons.json', JSON.stringify(stickers), function (error) { + if (error) console.error(error); + }); + + } catch (tantrum) { + throw tantrum; + } + }); + }); +}); diff --git a/data/icons.json b/data/icons.json new file mode 100644 index 0000000..4ea3cca --- /dev/null +++ b/data/icons.json @@ -0,0 +1 @@ +[{"id":"🌀","background":"#ffffff","foreground":"#000000"},{"id":"🌁","background":"#ffffff","foreground":"#000000"},{"id":"🌂","background":"#ffffff","foreground":"#000000"},{"id":"🌃","background":"#ffffff","foreground":"#000000"},{"id":"🌄","background":"#ffffff","foreground":"#000000"},{"id":"🌅","background":"#ffffff","foreground":"#000000"},{"id":"🌆","background":"#ffffff","foreground":"#000000"},{"id":"🌇","background":"#ffffff","foreground":"#000000"},{"id":"🌈","background":"#ffffff","foreground":"#000000"},{"id":"🌉","background":"#ffffff","foreground":"#000000"},{"id":"🌊","background":"#ffffff","foreground":"#000000"},{"id":"🌋","background":"#ffffff","foreground":"#000000"},{"id":"🌌","background":"#ffffff","foreground":"#000000"},{"id":"🌏","background":"#ffffff","foreground":"#000000"},{"id":"🌑","background":"#ffffff","foreground":"#000000"},{"id":"🌓","background":"#ffffff","foreground":"#000000"},{"id":"🌔","background":"#ffffff","foreground":"#000000"},{"id":"🌕","background":"#ffffff","foreground":"#000000"},{"id":"🌙","background":"#ffffff","foreground":"#000000"},{"id":"🌛","background":"#ffffff","foreground":"#000000"},{"id":"🌟","background":"#ffffff","foreground":"#000000"},{"id":"🌠","background":"#ffffff","foreground":"#000000"},{"id":"🌰","foreground":"#000000","background":"#f8fefb"},{"id":"🌱","foreground":"#000000","background":"#f4fffc"},{"id":"🌴","background":"#ffffff","foreground":"#000000"},{"id":"🌵","background":"#ffffff","foreground":"#000000"},{"id":"🌷","background":"#ffffff","foreground":"#000000"},{"id":"🌸","background":"#ffffff","foreground":"#000000"},{"id":"🌹","background":"#ffffff","foreground":"#000000"},{"id":"🌺","background":"#ffffff","foreground":"#000000"},{"id":"🌻","background":"#ffffff","foreground":"#000000"},{"id":"🌼","background":"#ffffff","foreground":"#000000"},{"id":"🌽","foreground":"#000000","background":"#ffffff"},{"id":"🌾","background":"#ffffff","foreground":"#000000"},{"id":"🌿","background":"#ffffff","foreground":"#000000"},{"id":"🍀","background":"#ffffff","foreground":"#000000"},{"id":"🍁","background":"#ffffff","foreground":"#000000"},{"id":"🍂","background":"#ffffff","foreground":"#000000"},{"id":"🍃","background":"#ffffff","foreground":"#000000"},{"id":"🍄","background":"#ffffff","foreground":"#000000"},{"id":"🍅","background":"#ffffff","foreground":"#000000"},{"id":"🍆","background":"#ffffff","foreground":"#000000"},{"id":"🍇","background":"#ffffff","foreground":"#000000"},{"id":"🍈","background":"#ffffff","foreground":"#000000"},{"id":"🍉","background":"#ffffff","foreground":"#000000"},{"id":"🍊","background":"#ffffff","foreground":"#000000"},{"id":"🍌","background":"#ffffff","foreground":"#000000"},{"id":"🍍","background":"#ffffff","foreground":"#000000"},{"id":"🍎","background":"#ffffff","foreground":"#000000"},{"id":"🍏","background":"#ffffff","foreground":"#000000"},{"id":"🍑","background":"#ffffff","foreground":"#000000"},{"id":"🍒","background":"#ffffff","foreground":"#000000"},{"id":"🍓","background":"#ffffff","foreground":"#000000"},{"id":"🍔","background":"#ffffff","foreground":"#000000"},{"id":"🍕","background":"#ffffff","foreground":"#000000"},{"id":"🍖","background":"#ffffff","foreground":"#000000"},{"id":"🍗","background":"#ffffff","foreground":"#000000"},{"id":"🍘","background":"#ffffff","foreground":"#000000"},{"id":"🍙","background":"#ffffff","foreground":"#000000"},{"id":"🍚","background":"#ffffff","foreground":"#000000"},{"id":"🍛","background":"#ffffff","foreground":"#000000"},{"id":"🍜","background":"#ffffff","foreground":"#000000"},{"id":"🍝","background":"#ffffff","foreground":"#000000"},{"id":"🍞","background":"#ffffff","foreground":"#000000"},{"id":"🍟","background":"#ffffff","foreground":"#000000"},{"id":"🍠","background":"#ffffff","foreground":"#000000"},{"id":"🍡","background":"#ffffff","foreground":"#000000"},{"id":"🍢","background":"#ffffff","foreground":"#000000"},{"id":"🍣","background":"#ffffff","foreground":"#000000"},{"id":"🍤","background":"#ffffff","foreground":"#000000"},{"id":"🍥","background":"#ffffff","foreground":"#000000"},{"id":"🍦","background":"#ffffff","foreground":"#000000"},{"id":"🍧","background":"#ffffff","foreground":"#000000"},{"id":"🍨","background":"#ffffff","foreground":"#000000"},{"id":"🍩","background":"#ffffff","foreground":"#000000"},{"id":"🍪","background":"#ffffff","foreground":"#000000"},{"id":"🍫","background":"#ffffff","foreground":"#000000"},{"id":"🍬","background":"#ffffff","foreground":"#000000"},{"id":"🍭","background":"#ffffff","foreground":"#000000"},{"id":"🍮","background":"#ffffff","foreground":"#000000"},{"id":"🍯","background":"#ffffff","foreground":"#000000"},{"id":"🍰","background":"#ffffff","foreground":"#000000"},{"id":"🍱","background":"#ffffff","foreground":"#000000"},{"id":"🍲","background":"#ffffff","foreground":"#000000"},{"id":"🍳","background":"#ffffff","foreground":"#000000"},{"id":"🍴","background":"#ffffff","foreground":"#000000"},{"id":"🍵","background":"#ffffff","foreground":"#000000"},{"id":"🍶","background":"#ffffff","foreground":"#000000"},{"id":"🍷","background":"#ffffff","foreground":"#000000"},{"id":"🍸","background":"#ffffff","foreground":"#000000"},{"id":"🍹","background":"#ffffff","foreground":"#000000"},{"id":"🍺","background":"#ffffff","foreground":"#000000"},{"id":"🍻","background":"#ffffff","foreground":"#000000"},{"id":"🎀","background":"#ffffff","foreground":"#000000"},{"id":"🎁","background":"#ffffff","foreground":"#000000"},{"id":"🎂","background":"#ffffff","foreground":"#000000"},{"id":"🎃","background":"#ffffff","foreground":"#000000"},{"id":"🎄","background":"#ffffff","foreground":"#000000"},{"id":"🎅","background":"#ffffff","foreground":"#000000"},{"id":"🎆","background":"#ffffff","foreground":"#000000"},{"id":"🎇","background":"#ffffff","foreground":"#000000"},{"id":"🎈","background":"#ffffff","foreground":"#000000"},{"id":"🎉","background":"#ffffff","foreground":"#000000"},{"id":"🎊","background":"#ffffff","foreground":"#000000"},{"id":"🎋","background":"#ffffff","foreground":"#000000"},{"id":"🎌","background":"#ffffff","foreground":"#000000"},{"id":"🎍","background":"#ffffff","foreground":"#000000"},{"id":"🎎","background":"#ffffff","foreground":"#000000"},{"id":"🎏","background":"#ffffff","foreground":"#000000"},{"id":"🎐","background":"#ffffff","foreground":"#000000"},{"id":"🎑","background":"#ffffff","foreground":"#000000"},{"id":"🎒","background":"#ffffff","foreground":"#000000"},{"id":"🎓","background":"#ffffff","foreground":"#000000"},{"id":"🎠","background":"#ffffff","foreground":"#000000"},{"id":"🎡","background":"#ffffff","foreground":"#000000"},{"id":"🎢","background":"#ffffff","foreground":"#000000"},{"id":"🎣","background":"#ffffff","foreground":"#000000"},{"id":"🎤","background":"#ffffff","foreground":"#000000"},{"id":"🎥","background":"#ffffff","foreground":"#000000"},{"id":"🎦","background":"#ffffff","foreground":"#000000"},{"id":"🎧","background":"#ffffff","foreground":"#000000"},{"id":"🎨","background":"#ffffff","foreground":"#000000"},{"id":"🎩","background":"#ffffff","foreground":"#000000"},{"id":"🎪","background":"#ffffff","foreground":"#000000"},{"id":"🎫","background":"#ffffff","foreground":"#000000"},{"id":"🎬","background":"#ffffff","foreground":"#000000"},{"id":"🎭","background":"#ffffff","foreground":"#000000"},{"id":"🎮","background":"#ffffff","foreground":"#000000"},{"id":"🎯","background":"#ffffff","foreground":"#000000"},{"id":"🎰","background":"#ffffff","foreground":"#000000"},{"id":"🎱","background":"#ffffff","foreground":"#000000"},{"id":"🎲","background":"#ffffff","foreground":"#000000"},{"id":"🎳","background":"#ffffff","foreground":"#000000"},{"id":"🎴","background":"#ffffff","foreground":"#000000"},{"id":"🎵","background":"#ffffff","foreground":"#000000"},{"id":"🎶","background":"#ffffff","foreground":"#000000"},{"id":"🎷","background":"#ffffff","foreground":"#000000"},{"id":"🎸","background":"#ffffff","foreground":"#000000"},{"id":"🎹","background":"#ffffff","foreground":"#000000"},{"id":"🎺","background":"#ffffff","foreground":"#000000"},{"id":"🎻","background":"#ffffff","foreground":"#000000"},{"id":"🎼","background":"#ffffff","foreground":"#000000"},{"id":"🎽","background":"#ffffff","foreground":"#000000"},{"id":"🎾","background":"#ffffff","foreground":"#000000"},{"id":"🎿","background":"#ffffff","foreground":"#000000"},{"id":"🏀","background":"#ffffff","foreground":"#000000"},{"id":"🏁","background":"#ffffff","foreground":"#000000"},{"id":"🏂","background":"#ffffff","foreground":"#000000"},{"id":"🏃","background":"#ffffff","foreground":"#000000"},{"id":"🏄","background":"#ffffff","foreground":"#000000"},{"id":"🏆","background":"#ffffff","foreground":"#000000"},{"id":"🏈","background":"#ffffff","foreground":"#000000"},{"id":"🏊","background":"#ffffff","foreground":"#000000"},{"id":"🏠","background":"#ffffff","foreground":"#000000"},{"id":"🏡","background":"#ffffff","foreground":"#000000"},{"id":"🏢","background":"#ffffff","foreground":"#000000"},{"id":"🏣","background":"#ffffff","foreground":"#000000"},{"id":"🏥","background":"#ffffff","foreground":"#000000"},{"id":"🏦","background":"#ffffff","foreground":"#000000"},{"id":"🏧","background":"#ffffff","foreground":"#000000"},{"id":"🏨","background":"#ffffff","foreground":"#000000"},{"id":"🏩","background":"#ffffff","foreground":"#000000"},{"id":"🏪","background":"#ffffff","foreground":"#000000"},{"id":"🏫","background":"#ffffff","foreground":"#000000"},{"id":"🏬","background":"#ffffff","foreground":"#000000"},{"id":"🏭","background":"#ffffff","foreground":"#000000"},{"id":"🏮","background":"#ffffff","foreground":"#000000"},{"id":"🏯","background":"#ffffff","foreground":"#000000"},{"id":"🍯","background":"#ffffff","foreground":"#000000"},{"id":"👯","background":"#ffffff","foreground":"#000000"},{"id":"💏","background":"#ffffff","foreground":"#000000"}] \ No newline at end of file diff --git a/package.json b/package.json index cfab1e0..967b026 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,14 @@ { - "name": "stickers", - "description": "just some good clean fun", - "version": "0.0.0", - "private": true, - "dependencies": { - "express": "3.4.4" - } + "name": "application-name", + "version": "0.0.1", + "private": true, + "scripts": { + "start": "node app.js" + }, + "dependencies": { + "express": "3.4.4", + "hjs": "*", + "stylus": "*", + "websocket": "~1.0.8" + } } diff --git a/public/components/icon_editor.hjs b/public/components/icon_editor.hjs new file mode 100644 index 0000000..1bc14e7 --- /dev/null +++ b/public/components/icon_editor.hjs @@ -0,0 +1,12 @@ +
+
+
+
+ +
+
diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..e69de29 diff --git a/public/javascripts/hogan.js b/public/javascripts/hogan.js new file mode 100644 index 0000000..09170d6 --- /dev/null +++ b/public/javascripts/hogan.js @@ -0,0 +1,500 @@ +/* + * Copyright 2011 Twitter, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var HoganTemplate = (function () { + + function constructor(text) { + this.text = text; + }; + + constructor.prototype = { + // render: replaced by generated code. + r: function (context, partials) { return ''; }, + + // variable escaping + v: hoganEscape, + + render: function render(context, partials) { + return this.r(context, partials); + }, + + // tries to find a partial in the curent scope and render it + rp: function(name, context, partials, indent) { + var partial = partials[name]; + + if (!partial) { + return ''; + } + + return partial.render(context, partials); + }, + + // render a section + rs: function(context, partials, section) { + var buf = ''; + var tail = context[context.length - 1]; + if (!isArray(tail)) { + buf = section(context, partials); + return buf; + } + + for (var i = 0; i < tail.length; i++) { + context.push(tail[i]); + buf += section(context, partials); + context.pop(); + } + return buf; + }, + + // maybe start a section + s: function(val, ctx, partials, inverted, start, end) { + if (isArray(val) && val.length === 0) { + return false; + } + + if (!inverted && typeof val == 'function') { + val = this.ls(val, ctx, partials, start, end); + } + + var pass = (val === '') || !!val; + + if (!inverted && pass && ctx) { + ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]); + } + + return pass; + }, + + // find values with dotted names + d: function(key, ctx, partials, returnFound) { + if (key === '.' && isArray(ctx[ctx.length - 2])) { + return ctx[ctx.length - 1]; + } + + var names = key.split('.'); + var val = this.f(names[0], ctx, partials, returnFound); + var cx = null; + for (var i = 1; i < names.length; i++) { + if (val && typeof val == 'object' && names[i] in val) { + cx = val; + val = val[names[i]]; + } else { + val = ''; + } + } + + if (returnFound && !val) { + return false; + } + + if (!returnFound && typeof val == 'function') { + ctx.push(cx); + val = this.lv(val, ctx, partials); + ctx.pop(); + } + + return val; + }, + + // find values with normal names + f: function(key, ctx, partials, returnFound) { + var val = false; + var v = null; + var found = false; + + for (var i = ctx.length - 1; i >= 0; i--) { + v = ctx[i]; + if (v && typeof v == 'object' && key in v) { + val = v[key]; + found = true; + break; + } + } + + if (!found) { + return (returnFound) ? false : ""; + } + + if (!returnFound && typeof val == 'function') { + val = this.lv(val, ctx, partials); + } + + return val; + }, + + // higher order templates + ho: function(val, cx, partials, text) { + var t = val.call(cx, text, function(t) { + return Hogan.compile(t).render(cx); + }); + var s = Hogan.compile(t.toString()).render(cx, partials); + this.b = s; + return false; + }, + + // higher order template result buffer + b: '', + + // lambda replace section + ls: function(val, ctx, partials, start, end) { + var cx = ctx[ctx.length - 1]; + if (val.length > 0) { + return this.ho(val, cx, partials, this.text.substring(start, end)); + } + var t = val.call(cx); + if (typeof t == 'function') { + return this.ho(t, cx, partials, this.text.substring(start, end)); + } + return t; + }, + + // lambda replace variable + lv: function(val, ctx, partials) { + var cx = ctx[ctx.length - 1]; + return Hogan.compile(val.call(cx).toString()).render(cx, partials); + } + }; + + var rAmp = /&/g, rLt = //g, rApos =/\'/g, + rQuot = /\"/g, hChars =/[&<>\"\']/; + function hoganEscape(str) { + var s = String(str === null ? '' : str); + return hChars.test(s) ? s.replace(rAmp,'&') + .replace(rLt,'<').replace(rGt,'>') + .replace(rApos,''').replace(rQuot, '"') : s; + } + + var isArray = Array.isArray || function(a) { + return Object.prototype.toString.call(a) === '[object Array]'; + } + + return constructor; +})(); + +var Hogan = (function () { + + function scan(text) { + var len = text.length, + IN_TEXT = 0, + IN_TAG_TYPE = 1, + IN_TAG = 2, + state = IN_TEXT, + tagType = null, + buf = '', + tokens = [], + seenTag = false, + i = 0, + lineStart = 0, + otag = '{{', + ctag = '}}'; + + function addBuf() { + if (buf.length > 0) { + tokens.push(new String(buf)); + buf = ''; + } + } + + function lineIsWhitespace() { + var isAllWhitespace = true; + for (var j = lineStart; j < tokens.length; j++) { + isAllWhitespace = + (tokens[j].tag && tagTypes[tokens[j].tag] < tagTypes['_v']) || + (!tokens[j].tag && tokens[j].match(rIsWhitespace) == null); + if (!isAllWhitespace) { + return false; + } + } + + return isAllWhitespace; + } + + function filterLine(haveSeenTag, noNewLine) { + addBuf(); + if (haveSeenTag && lineIsWhitespace()) { + for (var j = lineStart; j < tokens.length; j++) { + if (!tokens[j].tag) { + tokens.splice(j, 1); + } + } + } else if (!noNewLine) { + tokens.push({tag:'\n'}) + } + + seenTag = false; + lineStart = tokens.length; + } + + function changeDelimiters(text, index) { + var close = '=' + ctag; + var closeIndex = text.indexOf(close, index); + var delimiters = trim(text.substring(text.indexOf('=', index) + 1, + closeIndex)).split(' '); + otag = delimiters[0]; + ctag = delimiters[1]; + return closeIndex + close.length - 1; + } + + for (i = 0; i < len; i++) { + if (state == IN_TEXT) { + if (tagChange(otag, text, i)) { + --i; + addBuf(); + state = IN_TAG_TYPE; + } else { + if (text[i] == '\n') { + filterLine(seenTag); + } else { + buf += text[i]; + } + } + } else if (state == IN_TAG_TYPE) { + i += otag.length - 1; + var tag = tagTypes[text[i + 1]]; + tagType = tag ? text[i + 1] : '_v'; + seenTag = i; + if (tagType == '=') { + i = changeDelimiters(text, i); + state = IN_TEXT; + } else { + if (tag) { + i++; + } + state = IN_TAG; + } + } else { + if (tagChange(ctag, text, i)) { + i += ctag.length - 1; + tokens.push({tag: tagType, n: trim(buf), + i: (tagType == '/') ? seenTag - 1 : i + 1}); + buf = ''; + state = IN_TEXT; + if (tagType == '{') { + i++; + } + } else { + buf += text[i]; + } + } + } + + filterLine(seenTag, true); + + return tokens; + } + + function trim(s) { + if (s.trim) { + return s.trim(); + } + + return s.replace(/^\s*|\s*$/g, ''); + } + + // remove whitespace according to Mustache spec + var rIsWhitespace = /\S/; + + var tagTypes = { + '#': 1, '^': 2, '/': 3, '!': 4, '>': 5, + '<': 6, '=': 7, '_v': 8, '{': 9, '&': 10 + }; + + function tagChange(tag, text, index) { + if (text[index] != tag[0]) { + return false; + } + + for (var i = 1, l = tag.length; i < l; i++) { + if (text[index + i] != tag[i]) { + return false; + } + } + + return true; + } + + function buildTree(tokens, kind, stack, customTags) { + var instructions = [], + opener = null, + token = null; + + while (tokens.length > 0) { + token = tokens.shift(); + if (token.tag == '#' || token.tag == '^' || + isOpener(token, customTags)) { + stack.push(token); + token.nodes = buildTree(tokens, token.tag, stack, customTags); + instructions.push(token); + } else if (token.tag == '/') { + if (stack.length == 0) { + throw new Error('Closing tag without opener: /' + token.n); + } + opener = stack.pop(); + if (token.n != opener.n && !isCloser(token.n, opener.n, customTags)) { + throw new Error('Nesting error: ' + opener.n + ' vs. ' + token.n); + } + opener.end = token.i; + return instructions; + } else { + instructions.push(token); + } + } + + if (stack.length > 0) { + throw new Error('missing closing tag: ' + stack.pop().n); + } + + return instructions; + } + + function isOpener(token, tags) { + for (var i = 0, l = tags.length; i < l; i++) { + if (tags[i].o == token.n) { + token.tag = '#'; + return true; + } + } + } + + function isCloser(close, open, tags) { + for (var i = 0, l = tags.length; i < l; i++) { + if (tags[i].c == close && tags[i].o == open) { + return true; + } + } + } + + function generate(tree, text, options) { + var code = 'var c = [cx];var b = "";var _ = this;' + + walk(tree) + 'return b;'; + if (options.asString) { + return 'function(cx,p){' + code + ';};'; + } + + var template = new HoganTemplate(text); + template.r = new Function('cx', 'p', code); + return template; + } + + var rQuot = /\"/g, rNewline = /\n/g, rCr = /\r/g, rSlash = /\\/g; + function esc(s) { + return s.replace(rSlash, '\\\\') + .replace(rQuot, '\\\"') + .replace(rNewline, '\\n') + .replace(rCr, '\\r') + }; + + function chooseMethod(s) { + return (~s.indexOf('.')) ? 'd' : 'f'; + } + + function walk(tree) { + var code = ''; + for (var i = 0, l = tree.length; i < l; i++) { + var tag = tree[i].tag; + if (tag == '#') { + code += section(tree[i].nodes, tree[i].n, chooseMethod(tree[i].n), + tree[i].i, tree[i].end); + } else if (tag == '^') { + code += invertedSection(tree[i].nodes, tree[i].n, + chooseMethod(tree[i].n)); + } else if (tag == '<' || tag == '>') { + code += partial(tree[i].n); + } else if (tag == '{' || tag == '&') { + code += tripleStache(tree[i].n, chooseMethod(tree[i].n)); + } else if (tag == '\n') { + code += text('\n'); + } else if (tag == '_v') { + code += variable(tree[i].n, chooseMethod(tree[i].n)); + } else if (tag === undefined) { + code += text(tree[i]); + } + } + return code; + } + + function section(nodes, id, method, start, end) { + var code = 'if(_.s(_.' + method + '("' + esc(id) + '",c,p,1),'; + code += 'c,p,0,' + start + ',' + end + ')){'; + code += 'b += _.rs(c,p,'; + code += 'function(c,p){ var b = "";'; + code += walk(nodes); + code += 'return b;});c.pop();}'; + code += 'else{b += _.b; _.b = ""};'; + return code; + } + + function invertedSection(nodes, id, method) { + var code = 'if (!_.s(_.' + method + '("' + esc(id) + '",c,p,1),c,p,1,0,0)){'; + code += walk(nodes); + code += '};'; + return code; + } + + function partial(id) { + return 'b += _.rp("' + esc(id) + '",c[c.length - 1],p);'; + } + + function tripleStache(id, method) { + return 'b += (_.' + method + '("' + esc(id) + '",c,p,0));'; + } + + function variable(id, method) { + return 'b += (_.v(_.' + method + '("' + esc(id) + '",c,p,0)));'; + } + + function text(id) { + return 'b += "' + esc(id) + '";'; + } + + return ({ + scan: scan, + + parse: function(tokens, options) { + options = options || {}; + return buildTree(tokens, '', [], options.sectionTags || []); + }, + + cache: {}, + + compile: function(text, options) { + // options + // + // asString: false (default) + // + // sectionTags: [{o: '_foo', c: 'foo'}] + // An array of object with o and c fields that indicate names for custom + // section tags. The example above allows parsing of {{_foo}}{{/foo}}. + // + options = options || {}; + + var t = this.cache[text]; + if (t) { + return t; + } + t = generate(this.parse(scan(text), options), text, options); + return this.cache[text] = t; + } + }); +})(); + +// Export the hogan constructor for Node.js and CommonJS. +if (typeof module !== 'undefined' && module.exports) { + module.exports = Hogan; + module.exports.Template = HoganTemplate; +} else if (typeof exports !== 'undefined') { + exports.Hogan = Hogan; + exports.HoganTemplate = HoganTemplate; +} \ No newline at end of file diff --git a/public/javascripts/javascript.js b/public/javascripts/javascript.js new file mode 100644 index 0000000..a02b0f0 --- /dev/null +++ b/public/javascripts/javascript.js @@ -0,0 +1,96 @@ +;(function () { + var stickersContainer = document.getElementById('stickers'); + var stickers = stickersContainer.querySelectorAll('.js-sticker'); + var stickerEditor = document.getElementById('sticker-editor'); + var foregroundInput = stickerEditor.querySelector('.js-color--foreground'); + var backgroundInput = stickerEditor.querySelector('.js-color--background'); + var editorSticker = stickerEditor.querySelector('.js-sticker'); + var sock = new WebSocket('ws://' + location.host, 'wow'); + + window.addEventListener('click', function (event) { + var sticker = event.target; + if (!sticker.classList.contains('sticker')) return; + setEditorSticker({ + foreground: hex(sticker.style.color), + background: hex(sticker.style.background), + id: sticker.innerText + }); + showStickerEditor(); + }); + + function colorInputChange () { + var sticker = document.getElementById(editorSticker.innerText); + sticker.style.color = editorSticker.style.color = hex(foregroundInput.value); + sticker.style.background = editorSticker.style.background = hex(backgroundInput.value); + if (sock && sock.readyState == 1) { + sock.send(JSON.stringify({ + id: editorSticker.innerText, + foreground: hex(editorSticker.style.color), + background: hex(editorSticker.style.background) + })); + } else { + alert('sock is broke, plz refresh or connect to internet or something'); + } + } + + function decToHex (number) { + var hex = (+number).toString(16); + if (hex.length == 1) return '0' + hex; + return hex; + } + + function hex(color) { + if (~color.indexOf('#')) return color; + var colors = color.replace(/[rgb() ]/g, '').split(','); + return '#' + decToHex(colors [0]) + decToHex(colors [1]) + decToHex(colors [2]); + } + + function setEditorSticker (details) { + foregroundInput.value = editorSticker.style.color = hex(details.foreground); + backgroundInput.value = editorSticker.style.background = hex(details.background); + editorSticker.innerText = details.id; + editorSticker.id = 'editor-' + details.id; + } + + function hideStickerEditor () { + stickerEditor.classList.remove('is-shown'); + } + + function showStickerEditor () { + stickerEditor.classList.add('is-shown'); + } + + foregroundInput.addEventListener('change', colorInputChange); + backgroundInput.addEventListener('change', colorInputChange); + + stickerEditor.querySelector('.js-close').addEventListener('click', hideStickerEditor); + window.addEventListener('keydown', function (event) { + event.which == 27 && hideStickerEditor(); + }); + + sock.addEventListener('message', function (message) { + message = (function() { + try { + return JSON.parse(message.data); + } catch (error) { + return; + } + })(); + + if (!message) return; + + var sticker = document.getElementById(message.id); + var editorSticker = document.getElementById('editor' + message.id); + + if (sticker) { + sticker.style.color = message.foreground; + sticker.style.background = message.background; + } + + if (editorSticker) { + editorSticker.style.color = message.foreground; + editorticker.style.background = message.background; + } + }); + +})(); diff --git a/public/javascripts/main.js b/public/javascripts/main.js new file mode 100644 index 0000000..d7598d4 --- /dev/null +++ b/public/javascripts/main.js @@ -0,0 +1,20 @@ +(function(){ + function toggleClass (element, className) { + if (element.classList.contains(className)) { + element.classList.remove(className) + } else { + element.classList.add(className) + } + } + + window.addEventListener('click', function (event) { + var element = event.target; + var focused = document.querySelector('.focus') + if (focused) { + focused.classList.remove('focus') + } + if (element.tagName == 'I') { + toggleClass(element, 'focus') + } + }) +}) diff --git a/public/old.html b/public/old.html new file mode 100644 index 0000000..8c4c17a --- /dev/null +++ b/public/old.html @@ -0,0 +1,230 @@ + + + + + +🌀 +🌁 +🌂 +🌃 +🌄 +🌅 +🌆 +🌇 +🌈 +🌉 +🌊 +🌋 +🌌 +🌏 +🌑 +🌓 +🌔 +🌕 +🌙 +🌛 +🌟 +🌠 +🌰 +🌱 +🌴 +🌵 +🌷 +🌸 +🌹 +🌺 +🌻 +🌼 +🌽 +🌾 +🌿 +🍀 +🍁 +🍂 +🍃 +🍄 +🍅 +🍆 +🍇 +🍈 +🍉 +🍊 +🍌 +🍍 +🍎 +🍏 +🍑 +🍒 +🍓 +🍔 +🍕 +🍖 +🍗 +🍘 +🍙 +🍚 +🍛 +🍜 +🍝 +🍞 +🍟 +🍠 +🍡 +🍢 +🍣 +🍤 +🍥 +🍦 +🍧 +🍨 +🍩 +🍪 +🍫 +🍬 +🍭 +🍮 +🍯 +🍰 +🍱 +🍲 +🍳 +🍴 +🍵 +🍶 +🍷 +🍸 +🍹 +🍺 +🍻 +🎀 +🎁 +🎂 +🎃 +🎄 +🎅 +🎆 +🎇 +🎈 +🎉 +🎊 +🎋 +🎌 +🎍 +🎎 +🎏 +🎐 +🎑 +🎒 +🎓 +🎠 +🎡 +🎢 +🎣 +🎤 +🎥 +🎦 +🎧 +🎨 +🎩 +🎪 +🎫 +🎬 +🎭 +🎮 +🎯 +🎰 +🎱 +🎲 +🎳 +🎴 +🎵 +🎶 +🎷 +🎸 +🎹 +🎺 +🎻 +🎼 +🎽 +🎾 +🎿 +🏀 +🏁 +🏂 +🏃 +🏄 +🏆 +🏈 +🏊 +🏠 +🏡 +🏢 +🏣 +🏥 +🏦 +🏧 +🏨 +🏩 +🏪 +🏫 +🏬 +🏭 +🏮 +🏯 +🍯 +👯 +💏 diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css new file mode 100644 index 0000000..dc1b5ad --- /dev/null +++ b/public/stylesheets/style.css @@ -0,0 +1,88 @@ +body { + margin: auto; + background: #f7f7f7; + color: #333; + width: 90%; + text-align: center; +} +.sticker { + font-style: normal; + font-family: Android Emoji, Symbola, Apple Color Emoji; +} +.stickers__sticker { + font-size: 4em; + line-height: 1.2; + margin: 0.1em 0; + padding: 0; + border-radius: 15em; + border: 1px solid rgba(0,0,0,0.1); + display: inline-block; + cursor: pointer; +} +.modal-panel { + position: fixed; + top: 30%; + left: 25%; + width: 50%; + height: 50%; + background: #fff; + border: 1px solid #ccc; + border-bottom: 5px solid #acf; + box-shadow: 2px 2px 2px rgba(0,0,0,0.2); + transition: opacity 0.7s ease, top 0.5s ease-in-out; + opacity: 0; + pointer-events: none; +} +.modal-panel.is-shown { + top: 25%; + opacity: 1; + pointer-events: all; +} +.modal-panel__close { + position: absolute; + top: 0; + right: 0; + font-size: 1em; + width: 1.5em; + height: 1.5em; + line-height: 1.5em; + background: #c99; + border: #a77; + font-style: normal; + color: #fee; + cursor: pointer; +} +.modal-panel__close:before { + content: "✖"; +} +.sticker-editor__pane { + display: inline-table; + vertical-align: top; + width: 40%; + white-space: normal; +} +.sticker-editor__content { + width: 90%; + margin: 2em 0; + white-space: nowrap; +} +.sticker-editor__row { + display: table-row; + line-height: 2em; +} +.sticker-editor__h3 { + font-family: roboto, helvetica neue; + font-weight: 100; + color: #666; + text-align: left; + display: table-cell; + width: 0; +} +.sticker-editor__color { + display: table-cell; + width: 100%; +} +.sticker-editor__sticker { + font-size: 10em; + border-radius: 100%; +} diff --git a/public/stylesheets/style.styl b/public/stylesheets/style.styl new file mode 100644 index 0000000..a8a32b6 --- /dev/null +++ b/public/stylesheets/style.styl @@ -0,0 +1,90 @@ +$sticker-font = Android Emoji, Symbola, Apple Color Emoji + +body + margin: auto + background: #f7f7f7 + color: #333 + width: 90% + text-align: center + +.sticker + font-style: normal + font-family: $sticker-font + +.stickers__sticker + font-size: 4em + line-height: 1.2 + margin: .1em 0 + padding: 0 + border-radius: 15em + border: 1px solid rgba( 0, 0, 0, 0.1 ) + display: inline-block + cursor: pointer + +.modal-panel + position: fixed + top: 30% + left: 25% + width: 50% + height: 50% + background: #fff + border: 1px solid #ccc + border-bottom: 5px solid #acf + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.2) + transition: opacity .7s ease, top .5s ease-in-out + opacity: 0 + pointer-events: none + +.modal-panel.is-shown + top: 25% + opacity: 1 + pointer-events: all + +.modal-panel__close + $font-size = 1em + $size = 1.5em + position: absolute + top: 0 + right: 0 + font-size: $font-size + width: $size + height: $size + line-height: $size + background: #c99 + border: #a77 + font-style: normal + color: #fee + cursor: pointer + &:before + content: "✖" + +.sticker-editor__pane + display: inline-table + vertical-align: top + width: 40% + white-space: normal + +.sticker-editor__content + width: 90% + margin: 2em 0 + white-space: nowrap + +.sticker-editor__row + display: table-row + line-height: 2em + +.sticker-editor__h3 + font-family: roboto, helvetica neue + font-weight: 100 + color: #666 + text-align: left + display: table-cell + width: 0 + +.sticker-editor__color + display: table-cell + width: 100% + +.sticker-editor__sticker + font-size: 10em + border-radius: 100% diff --git a/routes/index.js b/routes/index.js new file mode 100644 index 0000000..5c57e46 --- /dev/null +++ b/routes/index.js @@ -0,0 +1,15 @@ +/* + * GET home page. + */ +var fs = require('fs'); +exports.index = function(req, res) { + fs.readFile('data/icons.json', function (up, buffer) { + if (up) throw up; + try { + var stickers = JSON.parse(buffer.toString()); + res.render('index', { stickers: stickers}); + } catch (tantrum) { + throw tantrum; + } + }); +}; diff --git a/routes/user.js b/routes/user.js new file mode 100644 index 0000000..d5b34aa --- /dev/null +++ b/routes/user.js @@ -0,0 +1,8 @@ + +/* + * GET users listing. + */ + +exports.list = function(req, res){ + res.send("respond with a resource"); +}; \ No newline at end of file diff --git a/views/index.hjs b/views/index.hjs new file mode 100644 index 0000000..aa98b74 --- /dev/null +++ b/views/index.hjs @@ -0,0 +1,32 @@ + + + let's play: stickers! + +
+ {{#stickers}} + + {{id}} + + {{/stickers}} +
+ + + +