summaryrefslogtreecommitdiffstats
path: root/web/js/labitrack.d
diff options
context:
space:
mode:
Diffstat (limited to 'web/js/labitrack.d')
-rw-r--r--web/js/labitrack.d/00-init.js6
-rw-r--r--web/js/labitrack.d/01-console.js5
-rw-r--r--web/js/labitrack.d/03-labitrack.js104
-rw-r--r--web/js/labitrack.d/05-utils.js36
-rw-r--r--web/js/labitrack.d/08-tags.js24
-rw-r--r--web/js/labitrack.d/10-template-standard.js252
-rw-r--r--web/js/labitrack.d/15-ratelimit.js44
-rw-r--r--web/js/labitrack.d/20-topbar.js13
-rw-r--r--web/js/labitrack.d/30-setcontent.js12
-rw-r--r--web/js/labitrack.d/31-handlebars-helpers.js17
-rw-r--r--web/js/labitrack.d/35-object.js20
-rw-r--r--web/js/labitrack.d/38-labelform.js60
-rw-r--r--web/js/labitrack.d/40-router.js58
-rw-r--r--web/js/labitrack.d/41-create.js29
-rw-r--r--web/js/labitrack.d/42-history.js9
-rw-r--r--web/js/labitrack.d/43-browse.js104
-rw-r--r--web/js/labitrack.d/44-about.js9
-rw-r--r--web/js/labitrack.d/45-view.js28
-rw-r--r--web/js/labitrack.d/46-edit.js44
-rw-r--r--web/js/labitrack.d/47-recent.js54
-rw-r--r--web/js/labitrack.d/90-start.js19
-rw-r--r--web/js/labitrack.d/99-end.js1
22 files changed, 948 insertions, 0 deletions
diff --git a/web/js/labitrack.d/00-init.js b/web/js/labitrack.d/00-init.js
new file mode 100644
index 0000000..7623738
--- /dev/null
+++ b/web/js/labitrack.d/00-init.js
@@ -0,0 +1,6 @@
+(function(undef){
+ var λ = {pub:{}};
+
+ window.labitrack = λ.pub;
+
+// end of 00-init.js
diff --git a/web/js/labitrack.d/01-console.js b/web/js/labitrack.d/01-console.js
new file mode 100644
index 0000000..4bd6def
--- /dev/null
+++ b/web/js/labitrack.d/01-console.js
@@ -0,0 +1,5 @@
+(function(){
+ if (window.console === undefined) {
+ window.console = { log: function(){} };
+ }
+}());
diff --git a/web/js/labitrack.d/03-labitrack.js b/web/js/labitrack.d/03-labitrack.js
new file mode 100644
index 0000000..6da295e
--- /dev/null
+++ b/web/js/labitrack.d/03-labitrack.js
@@ -0,0 +1,104 @@
+(function(){
+ λ.label = function(){
+ var mindata = {
+ id: "???",
+ name: "Name",
+ desc: "Description",
+ tags: []
+ };
+
+ var render;
+
+ function label()
+ {
+ this.canvas = null;
+ this.bitmap = null;
+ this.data = null;
+ this.busy = false;
+ this.set_template('standard');
+ this.renderpreview = new λ.ratelimiter(50, render, this);
+ }
+ var labelpt = label.prototype;
+
+ labelpt.set_template = function(tmpl){
+ this.template = λ.templates.get(tmpl);
+ this.update_canvas();
+ };
+
+ labelpt.set_canvas = function(canvas){
+ this.canvas = canvas;
+ this.update_canvas();
+ };
+
+ labelpt.set_data = function(data){
+ this.data = data;
+ this.render();
+ };
+
+ render = function(callback, preview){
+ if (preview === undef) preview = true;
+ var t = this;
+ var data = null;
+ var params = $.extend({}, mindata, t.data);
+ var time = labitrack.utils.time(function(){
+ t.busy = true;
+ data = t.template.draw(params, preview);
+ if (!preview) {
+ labitrack.utils.convert_to_monochrome(data);
+ } else {
+ t.bitmap = data;
+ t.update_canvas();
+ }
+ t.busy = false;
+ });
+ if (callback) {
+ callback.apply(t, [data, time]);
+ }
+ };
+
+ labelpt.render = function(callback, preview){
+ if (preview === false) {
+ return render.apply(this, [callback, preview]);
+ }
+ return this.renderpreview(callback);
+ };
+
+ labelpt.update_canvas = function(){
+ var bitmap = this.bitmap;
+ var canvas = this.canvas;
+ if (bitmap !== null && canvas !== null) {
+ canvas.width = bitmap.width;
+ canvas.height = bitmap.height;
+ var ctx = canvas.getContext('2d');
+ ctx.putImageData(bitmap, 0, 0);
+ }
+ };
+
+ labelpt.print = function(){
+ console.log("Print label on server");
+ this.render(function(data){
+ var ctx = labitrack.utils.new_context(data.width, data.height);
+ ctx.putImageData(data, 0, 0);
+ $.post('/print.json',
+ {
+ image: ctx.canvas.toDataURL('image/png')
+ }, function(data) { console.log('uploaded');}, 'json');
+ }, false);
+ };
+
+ return label;
+ }();
+
+ λ.templates = function(){
+ var templates = {};
+
+ return {
+ 'register': function(key, value){
+ templates[key] = value;
+ },
+ 'get': function(key){
+ return templates[key];
+ }
+ };
+ }();
+}());
diff --git a/web/js/labitrack.d/05-utils.js b/web/js/labitrack.d/05-utils.js
new file mode 100644
index 0000000..12822da
--- /dev/null
+++ b/web/js/labitrack.d/05-utils.js
@@ -0,0 +1,36 @@
+(function(labitrack){
+
+labitrack.utils = {};
+labitrack.utils.new_context = function(w, h){
+ var canvas = document.createElement('canvas');
+ canvas.width = w;
+ canvas.height = h;
+ return canvas.getContext('2d');
+};
+
+// Color quantization using Euclidean distance
+// https://en.wikipedia.org/wiki/Euclidean_distance
+// We don't do any alpha blending for now
+labitrack.utils.convert_to_monochrome = function(data){
+ var p = data.data;
+ for(var i = 0, l = p.length; i < l; i+=4) {
+ var v = (p[i+3] === 0 // handle alpha
+ ||
+ (Math.pow(p[i], 2) + Math.pow(p[i+1], 2) + Math.pow(p[i+2], 2))
+ >
+ (Math.pow(255-p[i], 2) + Math.pow(255-p[i+1], 2) + Math.pow(255-p[i+2], 2))
+ ) * 255;
+ p[i] = p[i+1] = p[i+2] = v;
+ p[i+3] = 255;
+ }
+};
+
+labitrack.utils.time = function(callback){
+ var start = Date.now();
+ var end = start;
+ callback();
+ end = Date.now();
+ return end - start;
+};
+
+}(labitrack));
diff --git a/web/js/labitrack.d/08-tags.js b/web/js/labitrack.d/08-tags.js
new file mode 100644
index 0000000..48ae6d5
--- /dev/null
+++ b/web/js/labitrack.d/08-tags.js
@@ -0,0 +1,24 @@
+(function(){
+ λ.tags = [
+ {
+ name: 'person',
+ desc: 'Owned by a member (not by Labitat)'
+ },
+ {
+ name: 'manual',
+ desc: 'Read the manual before use'
+ },
+ {
+ name: 'dnh',
+ desc: 'Do not hack'
+ },
+ /*{
+ name: 'dne',
+ desc: 'Do not eat'
+ },
+ {
+ name: 'dohack',
+ desc: 'Do hack'
+ }*/
+ ];
+}());
diff --git a/web/js/labitrack.d/10-template-standard.js b/web/js/labitrack.d/10-template-standard.js
new file mode 100644
index 0000000..09a8fc1
--- /dev/null
+++ b/web/js/labitrack.d/10-template-standard.js
@@ -0,0 +1,252 @@
+λ.templates.register('standard', function(){
+
+ var qrcode = null;
+ var qrcode_url = null;
+ var left=1;
+ var right=2;
+
+ function drawCircle(ctx) {
+ ctx.beginPath();
+ ctx.arc(40, 0, 40, 0, Math.PI*2);
+ ctx.lineWidth = 8;
+ ctx.stroke();
+ ctx.closePath();
+ }
+
+ function roundedRect(ctx, x, y, w, h, r) {
+ ctx.save();
+ ctx.translate(x, y);
+ ctx.moveTo(0, r);
+ ctx.arc(r, r, r, Math.PI, Math.PI*1.5);
+ ctx.lineTo(w-r, 0);
+ ctx.arc(w-r, r, r, Math.PI*1.5, Math.PI*2);
+ ctx.lineTo(w, h-r);
+ ctx.arc(w-r, h-r, r, 0, Math.PI*0.5);
+ ctx.lineTo(r, h);
+ ctx.arc(r, h-r, r, Math.PI*0.5, Math.PI);
+ ctx.lineTo(0, r);
+ ctx.restore();
+ }
+
+ function measureCircle(ctx) {
+ return {width: 82, align: left};
+ }
+
+ function drawPerson(ctx, x, y) {
+ var m = this.measure(ctx);
+ ctx.save();
+ ctx.translate(x, y);
+
+ drawCircle(ctx);
+
+ ctx.beginPath();
+ ctx.arc(40, -25, 7.5, 0, Math.PI*2);
+ ctx.rect(32, -15, 16, 3);
+ ctx.moveTo(32, -12);
+ ctx.arc(32, -12, 2.5, Math.PI*1, Math.PI*1.5);
+ ctx.moveTo(48, -12);
+ ctx.arc(48, -12, 2.5, Math.PI*1.5, Math.PI*2);
+ ctx.rect(28, -12, 24, 20);
+ ctx.rect(32, 8, 16, 20);
+ ctx.fill();
+ ctx.closePath();
+
+ ctx.restore();
+
+ return m.width;
+ }
+
+ var stamplinewidth = 8;
+
+ function drawManual(ctx, x, y) {
+ var m = this.measure(ctx);
+ ctx.save();
+ ctx.translate(x, y);
+
+ drawCircle(ctx);
+
+ ctx.beginPath();
+ ctx.moveTo(6, -25);
+ roundedRect(ctx, 20, -25, 30, 40, 5);
+ roundedRect(ctx, 30, -15, 30, 40, 5);
+ ctx.lineWidth = 4;
+ ctx.stroke();
+ ctx.closePath();
+
+ ctx.restore();
+
+ return m.width;
+ }
+
+
+ function measureStamp(ctx, label)
+ {
+ ctx.font = '60px sans-serif';
+ var tm = ctx.measureText(label);
+ return {width: tm.width + 40 + 8, align: right};
+ }
+
+ function drawStamp(ctx, label, x, y)
+ {
+ ctx.save();
+ ctx.translate(x, y);
+
+ ctx.font = '60px sans-serif';
+ var tm = ctx.measureText(label);
+
+ ctx.beginPath();
+ var m = this.measure(ctx, label);
+ ctx.rect(stamplinewidth/2, -40, m.width - stamplinewidth, 80+(stamplinewidth/2), Math.PI*2);
+ ctx.lineWidth = stamplinewidth;
+ ctx.stroke();
+ ctx.closePath();
+
+ ctx.fillText(label, (m.width - stamplinewidth - tm.width)/2, 20);
+
+ ctx.restore();
+ return m.width;
+ }
+
+ var symbols = function(){
+ var symbols = {};
+
+ function register(key, draw, measure) {
+ symbols[key] = {draw: draw, measure: measure};
+ }
+ function get() {
+ return symbols;
+ }
+ return {get: get, register: register};
+ }();
+
+ function registerStamp(key, label) {
+ symbols.register(key,
+ function(ctx, x, y){
+ return drawStamp.apply(this, [ctx, label, x, y]);
+ },
+ function(ctx){
+ return measureStamp(ctx, label);
+ });
+ }
+
+ registerStamp('dnh', 'DNH');
+ registerStamp('dohack', 'DO HACK');
+ registerStamp('dne', 'DNE');
+ symbols.register('person', drawPerson, measureCircle);
+ symbols.register('manual', drawManual, measureCircle);
+
+ function drawQRcode(ctx, size, url) {
+ if (qrcode_url !== url) {
+ qrcode = null;
+ qrcode_url = url;
+ }
+ if (qrcode === null) {
+ // calculate the qrcode
+ qrcode = new QRCode(-1, QRErrorCorrectLevel.L);
+ qrcode.addData(url);
+ qrcode.make();
+ }
+
+ ctx.save();
+ var scale = size / qrcode.getModuleCount();
+ ctx.scale(scale, scale);
+
+ // draw on the canvas
+ ctx.beginPath();
+ for (var row = 0; row < qrcode.getModuleCount(); row++){
+ for (var col=0; col < qrcode.getModuleCount(); col++){
+ if (qrcode.isDark(row, col)) {
+ ctx.rect(col, row, 1, 1);
+ }
+ }
+ }
+ ctx.closePath();
+ ctx.fill();
+ ctx.restore();
+ }
+
+ function draw(data, preview)
+ {
+ var dw;
+ if (preview) {
+ dw = 560;
+ } else {
+ dw = 1083;
+ }
+ var w = 1083;
+ var ds = dw/w;
+ var h = 336;
+ var dh = Math.round(h * ds);
+ var ctx = labitrack.utils.new_context(dw, dh);
+ ctx.scale(ds, ds)
+
+ ctx.shadowBlur = 0;
+ ctx.globalAlpha = 1;
+
+ drawQRcode(ctx, h, 'http://o.labitat.dk/'+data.id);
+
+ ctx.translate(h, 0);
+ var y = 50;
+ ctx.font = 'bold 40px sans-serif';
+ ctx.fillText(data.name, 20, y);
+ y += 45;
+ ctx.font = '40px sans-serif';
+ ctx.fillText('ID: '+data.id, 20, y);
+ y += 40;
+ var lines = data.desc.split('\n');
+ for (var i=0; i<lines.length;i++) {
+ ctx.fillText(lines[i], 20, y);
+ y += 40;
+ }
+
+ function drawline(y, x, w) {
+ ctx.save();
+ ctx.beginPath();
+ ctx.moveTo(x, y);
+ ctx.lineTo(x+w, y);
+ ctx.strokeStyle = 'red 1px';
+ ctx.stroke();
+ ctx.closePath();
+ ctx.restore();
+ }
+
+ function drawSymbols(ctx) {
+ var l = 20;
+ var r = 750;
+ var y = 280;
+ var p = 15;
+
+ var tags = data.tags;
+ var syms = symbols.get();
+ for (tag in syms) {
+ var found = false;
+ for (var i=0; i<tags.length; i++) {
+ if (tag === tags[i]) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) continue;
+
+ var sym = syms[tag];
+
+ var m = sym.measure(ctx);
+ if (m.align === left) {
+ //drawline(y-50-(i*10), l, m.width);
+ l += sym.draw(ctx, l, y) + p;
+ } else {
+ r -= m.width + p;
+ //drawline(y-50-(i*10), r, m.width);
+ sym.draw(ctx, r, y);
+ }
+ }
+ }
+
+ drawSymbols(ctx);
+
+ return ctx.getImageData(0, 0, dw, dh);
+ }
+
+ return {'draw': draw};
+
+}());
diff --git a/web/js/labitrack.d/15-ratelimit.js b/web/js/labitrack.d/15-ratelimit.js
new file mode 100644
index 0000000..0af1ddc
--- /dev/null
+++ b/web/js/labitrack.d/15-ratelimit.js
@@ -0,0 +1,44 @@
+(function(){
+ function ratelimiter(args) {
+ this.in_progress = null;
+ this.needs_triggering = null;
+ this.callback = args[1];
+ this.ctx = args[2];
+ this.wait = args[0];
+ }
+
+ var rlpt = ratelimiter.prototype;
+
+ function trigger()
+ {
+ var t = this;
+ setTimeout(function(){
+ var args = t.in_progress;
+ t.in_progress = null;
+ if (t.needs_triggering !== null) {
+ t.in_progress = t.needs_triggering;
+ t.needs_triggering = null;
+ setTimeout(function(){
+ trigger.call(t);
+ }, 0);
+ }
+ t.callback.apply(t.ctx, args);
+ }, t.wait);
+ }
+
+ rlpt.kick = function(args){
+ if (this.in_progress !== null) {
+ this.needs_triggering = args;
+ } else {
+ this.in_progress = args;
+ trigger.apply(this);
+ }
+ };
+
+ λ.ratelimiter = function(){
+ var rl = new ratelimiter(arguments);
+ return function(){
+ rl.kick(arguments);
+ };
+ };
+}());
diff --git a/web/js/labitrack.d/20-topbar.js b/web/js/labitrack.d/20-topbar.js
new file mode 100644
index 0000000..fdebd6d
--- /dev/null
+++ b/web/js/labitrack.d/20-topbar.js
@@ -0,0 +1,13 @@
+(function(){
+ λ.topbar = topbar = {};
+ topbar.update = function(){
+ console.log('topbar update');
+ $('ul.nav li a').each(function(){
+ if (this.href === window.location.href) {
+ $(this).parent().addClass('active');
+ } else {
+ $(this).parent().removeClass('active');
+ }
+ });
+ };
+}());
diff --git a/web/js/labitrack.d/30-setcontent.js b/web/js/labitrack.d/30-setcontent.js
new file mode 100644
index 0000000..d33a4c8
--- /dev/null
+++ b/web/js/labitrack.d/30-setcontent.js
@@ -0,0 +1,12 @@
+$(function(){
+ var template = λ.template = function (tmpl, context){
+ return Handlebars.templates[tmpl](context);
+ };
+
+ var tmplcontent = $('#tmplcontent');
+ var h1 = $('h1');
+ λ.setcontent = function(tmpl, context) {
+ tmplcontent.html(template(tmpl, context));
+ h1.html(tmplcontent.find('.tmplheader').html());
+ };
+});
diff --git a/web/js/labitrack.d/31-handlebars-helpers.js b/web/js/labitrack.d/31-handlebars-helpers.js
new file mode 100644
index 0000000..6fa462a
--- /dev/null
+++ b/web/js/labitrack.d/31-handlebars-helpers.js
@@ -0,0 +1,17 @@
+(function(){
+ Handlebars.registerHelper('labelform', function(){
+ return new Handlebars.SafeString(λ.template('labelform', this));
+ });
+ Handlebars.registerHelper('pagination', function(){
+ return new Handlebars.SafeString(λ.template('pagination', this));
+ });
+ Handlebars.registerHelper('dump_ctx', function(){
+ console.log({'ctx': this});
+ });
+ Handlebars.registerHelper('checked_tag', function(tags){
+ if (!$.isArray(tags)) return;
+ if (tags.indexOf(this.name) !== -1) {
+ return new Handlebars.SafeString(' checked="checked"');
+ }
+ });
+}());
diff --git a/web/js/labitrack.d/35-object.js b/web/js/labitrack.d/35-object.js
new file mode 100644
index 0000000..ae43895
--- /dev/null
+++ b/web/js/labitrack.d/35-object.js
@@ -0,0 +1,20 @@
+(function(){
+ var object = λ.o = Backbone.Model.extend({
+ defaults: {
+ name: 'Name',
+ desc: 'Description',
+ tags: []
+ },
+ url: function(){
+ var base = '/o';
+ if (this.isNew()) return base;
+ return base + '/' + this.id + '.json';
+ }
+ });
+
+ object.get = function(id, opts){
+ var o = new object({id: id});
+ o.fetch(opts);
+ return o;
+ };
+}());
diff --git a/web/js/labitrack.d/38-labelform.js b/web/js/labitrack.d/38-labelform.js
new file mode 100644
index 0000000..04031cf
--- /dev/null
+++ b/web/js/labitrack.d/38-labelform.js
@@ -0,0 +1,60 @@
+(function(){
+
+ λ.labelform = function(opts){
+ var model = opts.model;
+ var canvas = $('#label')[0];
+ var label = new λ.label();
+ label.set_data(model.toJSON());
+ label.set_canvas(canvas);
+
+ var rendertime = $('#rendertime');
+ function updateimg(data, ms) {
+ rendertime.text(ms);
+ }
+
+ var f = $('#labelform');
+ function update_data(){
+ var t = this;
+ setTimeout(function(){
+ var v = t.value;
+ var foo = {};
+ foo[t.name] = model.get(t.name);
+ switch (t.type) {
+ case 'text':
+ case 'textarea':
+ v = v.trim();
+ if (v.length === 0) {
+ v = $(t).attr('placeholder');
+ }
+ foo[t.name] = v.trim();
+ break;
+ case 'checkbox':
+ var i = $.inArray(v, foo[t.name]);
+ if (t.checked) {
+ if (i === -1) {
+ foo[t.name].push(t.value);
+ }
+ } else if (i !== -1) {
+ foo[t.name].splice(i, 1);
+ }
+ break;
+ }
+ model.set(foo);
+ label.set_data(model.toJSON());
+ label.render(updateimg);
+ }, 0);
+ };
+ f.find(':input').each(function (i,e){
+ $(e).bind('keypress', update_data);
+ $(e).bind('click', update_data);
+ $(e).bind('change', update_data);
+ update_data.apply(this);
+ });
+ label.render(updateimg);
+
+ f.bind('submit', function(){
+ opts.submit(label, model);
+ return false;
+ });
+ };
+}());
diff --git a/web/js/labitrack.d/40-router.js b/web/js/labitrack.d/40-router.js
new file mode 100644
index 0000000..153e0b1
--- /dev/null
+++ b/web/js/labitrack.d/40-router.js
@@ -0,0 +1,58 @@
+(function(){
+ var r = λ.r = new Backbone.Router();
+
+ function handle_click(event) {
+ console.log('click');
+ if (!Modernizr.history) return true;
+ event.preventDefault();
+ var href = $(event.target).attr('href');
+ if (href !== undef && href[0] === '/') {
+ Backbone.history.navigate(href, true);
+ }
+ }
+
+ var mainview = Backbone.View.extend({
+ events: {
+ 'click a': 'handleClick'
+ },
+ handleClick: handle_click,
+ initialize: function(){
+ _(this).bindAll('handleClick', 'render');
+ }
+ });
+ $(function(){
+ new mainview({el: document.body});
+ });
+
+ var view = Backbone.View.extend({
+ el: '#tmplcontent',
+ events: {
+ 'click a': 'handleClick'
+ },
+ handleClick: handle_click,
+ initialize: function(){
+ _(this).bindAll('handleClick', 'render');
+ }
+ });
+
+ function route_handler()
+ {
+ var t = this;
+ if (t.instance === undef) {
+ t.instance = new t();
+ }
+ t.instance.render.apply(t.instance, arguments);
+ };
+
+ view.route = function(route, name)
+ {
+ name || (name = route);
+ var t = this;
+ λ.r.route(route, name, function(){
+ λ.topbar.update();
+ route_handler.apply(t, arguments);
+ });
+ };
+
+ λ.routableview = view;
+}());
diff --git a/web/js/labitrack.d/41-create.js b/web/js/labitrack.d/41-create.js
new file mode 100644
index 0000000..ec689c4
--- /dev/null
+++ b/web/js/labitrack.d/41-create.js
@@ -0,0 +1,29 @@
+(function(){
+ function on_submit(label, o) {
+ o.save(undef, {
+ success: function(){
+ label.set_data(o.toJSON());
+ label.print();
+
+ console.log('Saved with id: ' + o.get('id'));
+ }
+ });
+ }
+
+ var view = λ.routableview.extend({
+ render: function () {
+ λ.setcontent('create', {
+ save_text: 'Save and queue for printing',
+ data: {},
+ tags: λ.tags
+ });
+ var o = new λ.o();
+ λ.labelform({
+ model: o,
+ submit: on_submit
+ });
+ }
+ });
+
+ view.route('', 'create');
+}());
diff --git a/web/js/labitrack.d/42-history.js b/web/js/labitrack.d/42-history.js
new file mode 100644
index 0000000..a64b29f
--- /dev/null
+++ b/web/js/labitrack.d/42-history.js
@@ -0,0 +1,9 @@
+(function(){
+ var view = λ.routableview.extend({
+ render: function () {
+ λ.setcontent('identify', {'page': 'history'});
+ }
+ });
+
+ view.route('history');
+}());
diff --git a/web/js/labitrack.d/43-browse.js b/web/js/labitrack.d/43-browse.js
new file mode 100644
index 0000000..7605e78
--- /dev/null
+++ b/web/js/labitrack.d/43-browse.js
@@ -0,0 +1,104 @@
+(function(){
+ function hdl_add(){
+ console.log('add');
+ }
+
+ function hdl_remove(){
+ console.log('remove');
+ }
+
+ function hdl_reset(){
+ console.log('reset');
+ this.render();
+ }
+
+ var collection = Backbone.Collection.extend({
+ model: λ.o,
+ url: function(){
+ return '/browse/'+(this.nextpage++)+'.json';
+ },
+ fetchpage: function(page){
+ if (page) {
+ this.nextpage = page;
+ }
+ this.fetch();;
+ },
+ comparator: function(object){
+ return object.id;
+ },
+ parse: function(data){
+ this.stats = {count: data.count};
+ console.log(data);
+ return data.objects;
+ }
+ });
+
+ var browse = Backbone.View.extend({
+ initialize: function() {
+ var messages = this.collection;
+ messages.bind("reset", hdl_reset, this);
+ messages.bind("add", hdl_add, this);
+ messages.bind("remove", hdl_remove, this);
+ },
+ render: function(page){
+ var stats = this.collection.stats;
+ var pages = [];
+ var dots = { id: 'dots', label: '…' };
+ pages.push({
+ id: 'first',
+ link: '/browse',
+ label: '|&larr;',
+ classes: 'prev'
+ });
+ pages.push({
+ id: 'prev',
+ link: '/browse',
+ label: '&larr;'
+ });
+ pages.push(dots);
+ pgno = 1;
+ pages.push({
+ id: pgno,
+ link: '/browse/'+pgno,
+ label: pgno
+ });
+ pages.push(dots);
+ pages.push({
+ id: 'next',
+ link: '/browse',
+ label: '&rarr;'
+ });
+ pages.push({
+ id: 'last',
+ link: '/browse',
+ label: '&rarr;|',
+ classes: 'next'
+ });
+ var data = {
+ rows: this.collection.toJSON(),
+ pages: pages
+ };
+ console.log(data);
+ $(this.el).html(λ.template('objecttable', data));
+ }
+ });
+
+ var collection = new collection();
+
+ var view = λ.routableview.extend({
+ initialize: function() {
+ λ.routableview.prototype.initialize.call(this);
+ this.browse = new browse({collection: collection});
+ },
+ render: function (page) {
+ page || (page = 1);
+ λ.setcontent('browse', {page: page});
+ this.browse.el = $(this.el).find('#objecttable_ph')[0];
+ this.browse.render(page);
+ this.browse.collection.fetchpage(page);
+ }
+ });
+
+ view.route('browse');
+ view.route('browse/:page');
+}());
diff --git a/web/js/labitrack.d/44-about.js b/web/js/labitrack.d/44-about.js
new file mode 100644
index 0000000..9bc03dc
--- /dev/null
+++ b/web/js/labitrack.d/44-about.js
@@ -0,0 +1,9 @@
+(function(){
+ var view = λ.routableview.extend({
+ render: function () {
+ λ.setcontent('about');
+ }
+ });
+
+ view.route('about');
+}());
diff --git a/web/js/labitrack.d/45-view.js b/web/js/labitrack.d/45-view.js
new file mode 100644
index 0000000..c94bc9e
--- /dev/null
+++ b/web/js/labitrack.d/45-view.js
@@ -0,0 +1,28 @@
+(function(){
+ var view = λ.routableview.extend({
+ render: function (id) {
+ var o = λ.o.get(id, {
+ success: function(){
+ λ.setcontent('view', {'id': id});
+ var canvas = $('#label')[0];
+ var label = new λ.label();
+ label.set_canvas(canvas);
+ label.set_data(o.toJSON());
+ $('.bnt_print').die().click(function(){
+ label.print();
+ return false;
+ });
+ },
+ error: function(ev){
+ λ.setcontent('notfound', {
+ action: 'View',
+ id: id,
+ status: ev.status
+ });
+ }
+ });
+ }
+ });
+
+ view.route('view/:id', 'view');
+}());
diff --git a/web/js/labitrack.d/46-edit.js b/web/js/labitrack.d/46-edit.js
new file mode 100644
index 0000000..c7039b0
--- /dev/null
+++ b/web/js/labitrack.d/46-edit.js
@@ -0,0 +1,44 @@
+(function(){
+ function on_submit(label, o)
+ {
+ o.save(undef, {success: function() {
+ label.set_data(o.toJSON());
+ Backbone.history.navigate('/view/'+o.id, true);
+ }});
+ }
+
+ function success(o)
+ {
+ var data = o.toJSON();
+ λ.setcontent('edit', {
+ id: o.id,
+ save_text: 'Save',
+ data: data,
+ tags: λ.tags
+ });
+
+ λ.labelform({
+ model: o,
+ submit: on_submit
+ });
+ }
+
+ var view = λ.routableview.extend({
+ render: function (id) {
+ var o = λ.o.get(id, {
+ success: function(){
+ success(o);
+ },
+ error: function(ev){
+ λ.setcontent('notfound', {
+ action: 'Edit',
+ id: id,
+ status: ev.status
+ });
+ }
+ });
+ }
+ });
+
+ view.route('edit/:id', 'edit');
+}());
diff --git a/web/js/labitrack.d/47-recent.js b/web/js/labitrack.d/47-recent.js
new file mode 100644
index 0000000..bb49e1f
--- /dev/null
+++ b/web/js/labitrack.d/47-recent.js
@@ -0,0 +1,54 @@
+(function(){
+ function hdl_add(){
+ console.log('add');
+ }
+
+ function hdl_remove(){
+ console.log('remove');
+ }
+
+ function hdl_reset(){
+ console.log('reset');
+ this.render();
+ }
+
+ var collection = Backbone.Collection.extend({
+ model: λ.o,
+ url: 'recent.json',
+ comparator: function(object){
+ return -object.get('updated');
+ }
+ });
+
+ var recent = Backbone.View.extend({
+ initialize: function() {
+ var messages = this.collection;
+ messages.bind("reset", hdl_reset, this);
+ messages.bind("add", hdl_add, this);
+ messages.bind("remove", hdl_remove, this);
+ },
+ render: function(){
+ var data = {
+ rows: this.collection.toJSON()
+ };
+ console.log(data);
+ $(this.el).html(λ.template('objecttable', data));
+ }
+ });
+
+ var view = λ.routableview.extend({
+ initialize: function() {
+ λ.routableview.prototype.initialize.call(this);
+ this.browse = new recent({collection: new collection()});
+ },
+ render: function (page) {
+ page || (page = 1);
+ λ.setcontent('recent');
+ this.browse.el = $(this.el).find('#objecttable_ph')[0];
+ this.browse.render();
+ this.browse.collection.fetch();
+ }
+ });
+
+ view.route('recent');
+}());
diff --git a/web/js/labitrack.d/90-start.js b/web/js/labitrack.d/90-start.js
new file mode 100644
index 0000000..b31a0cf
--- /dev/null
+++ b/web/js/labitrack.d/90-start.js
@@ -0,0 +1,19 @@
+$(function(){
+ function supportsToDataURL()
+ {
+ var c = document.createElement("canvas");
+ var data = c.toDataURL("image/png");
+ return (data.indexOf("data:image/png") == 0);
+ }
+
+ if (Modernizr.canvas
+ && Modernizr.canvastext
+ && Modernizr.fontface
+ && supportsToDataURL) {
+ Backbone.history.start({
+ pushState: true
+ });
+ } else {
+ λ.setcontent('ancientbrowser');
+ }
+});
diff --git a/web/js/labitrack.d/99-end.js b/web/js/labitrack.d/99-end.js
new file mode 100644
index 0000000..f48464f
--- /dev/null
+++ b/web/js/labitrack.d/99-end.js
@@ -0,0 +1 @@
+}());