summaryrefslogtreecommitdiff
path: root/public/assets/javascripts/ui/lib
diff options
context:
space:
mode:
Diffstat (limited to 'public/assets/javascripts/ui/lib')
-rw-r--r--public/assets/javascripts/ui/lib/AlertModal.js38
-rw-r--r--public/assets/javascripts/ui/lib/AnimatedView.js31
-rw-r--r--public/assets/javascripts/ui/lib/ConfirmModal.js46
-rw-r--r--public/assets/javascripts/ui/lib/ErrorModal.js38
-rw-r--r--public/assets/javascripts/ui/lib/FormView.js227
-rw-r--r--public/assets/javascripts/ui/lib/LabColorPicker.js180
-rw-r--r--public/assets/javascripts/ui/lib/ModalView.js79
-rw-r--r--public/assets/javascripts/ui/lib/Parser.js118
-rw-r--r--public/assets/javascripts/ui/lib/Router.js1
-rw-r--r--public/assets/javascripts/ui/lib/ToggleableView.js19
-rw-r--r--public/assets/javascripts/ui/lib/Toolbar.js22
-rw-r--r--public/assets/javascripts/ui/lib/UploadView.js152
-rw-r--r--public/assets/javascripts/ui/lib/View.js231
13 files changed, 787 insertions, 395 deletions
diff --git a/public/assets/javascripts/ui/lib/AlertModal.js b/public/assets/javascripts/ui/lib/AlertModal.js
index 1b0f40f..a4bf241 100644
--- a/public/assets/javascripts/ui/lib/AlertModal.js
+++ b/public/assets/javascripts/ui/lib/AlertModal.js
@@ -1,25 +1,25 @@
var AlertModal = new( ModalFormView.extend({
- el: ".mediaDrawer.alert",
+ el: ".mediaDrawer.alert",
- events: {
- "click .ok": "advance",
- "click .close": "advance",
- },
-
- alert: function(message, callback){
- this.$(".message").empty().append(message)
- this.callback = callback
- this.show()
- this.$(".ok").focus()
- },
-
- advance: function(e){
- e && e.preventDefault()
- this.hide()
- this.callback && this.callback()
- this.callback = null
- }
+ events: {
+ "click .ok": "advance",
+ "click .close": "advance",
+ },
+
+ alert: function(message, callback){
+ this.$(".message").empty().append(message)
+ this.callback = callback
+ this.show()
+ this.$(".ok").focus()
+ },
+
+ advance: function(e){
+ e && e.preventDefault()
+ this.hide()
+ this.callback && this.callback()
+ this.callback = null
+ }
}))
diff --git a/public/assets/javascripts/ui/lib/AnimatedView.js b/public/assets/javascripts/ui/lib/AnimatedView.js
new file mode 100644
index 0000000..3c50b0a
--- /dev/null
+++ b/public/assets/javascripts/ui/lib/AnimatedView.js
@@ -0,0 +1,31 @@
+var AnimatedView = View.extend({
+
+ _animating: false,
+ last_t: 0,
+
+ startAnimating: function(){
+ if (this._animating) return
+ this._animating = true
+ this._animate()
+ },
+
+ stopAnimating: function(){
+ this._animating = false
+ },
+
+ _animate: function(t){
+ if (! this._animating) return
+
+ requestAnimationFrame(this._animate.bind(this))
+
+ var dt = t - this.last_t
+ this.last_t = t
+
+ if (! t) return
+
+ this.animate(t, dt)
+ },
+
+ animate: function(t, dt){},
+
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/lib/ConfirmModal.js b/public/assets/javascripts/ui/lib/ConfirmModal.js
index 01720bb..7d9da67 100644
--- a/public/assets/javascripts/ui/lib/ConfirmModal.js
+++ b/public/assets/javascripts/ui/lib/ConfirmModal.js
@@ -1,24 +1,34 @@
var ConfirmModal = new( ModalFormView.extend({
- el: ".mediaDrawer.confirm",
+ el: ".mediaDrawer.confirm",
- events: {
- "click .yes": "advance",
- "click .no": "hide",
- },
-
- confirm: function(question, callback){
- this.$(".question").empty().append(question)
- this.callback = callback
- this.show()
- },
-
- advance: function(e){
- e && e.preventDefault()
- this.hide()
- this.callback && this.callback()
- this.callback = null
- }
+ events: {
+ "click .yes": "agree",
+ "click .no": "cancel",
+ },
+
+ confirm: function(question, agreeCallback, cancelCallback){
+ this.$(".question").empty().append(question)
+ this.agreeCallback = agreeCallback
+ this.cancelCallback = cancelCallback
+ this.show()
+ },
+
+ agree: function(e){
+ e && e.preventDefault()
+ this.hide()
+ this.agreeCallback && this.agreeCallback()
+ this.agreeCallback = null
+ this.cancelCallback = null
+ },
+
+ cancel: function(e){
+ e && e.preventDefault()
+ this.hide()
+ this.cancelCallback && this.cancelCallback()
+ this.agreeCallback = null
+ this.cancelCallback = null
+ }
}) ) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/lib/ErrorModal.js b/public/assets/javascripts/ui/lib/ErrorModal.js
index 8b01077..cfc2e6d 100644
--- a/public/assets/javascripts/ui/lib/ErrorModal.js
+++ b/public/assets/javascripts/ui/lib/ErrorModal.js
@@ -1,26 +1,26 @@
var ErrorModal = new( ModalFormView.extend({
- el: ".mediaDrawer.error",
+ el: ".mediaDrawer.error",
- events: {
- "click .ok": "advance",
- "click .close": "advance",
- },
-
- alert: function(message, callback){
- this.$(".errorList").empty().append(message)
- this.callback = callback
- this.show()
- this.$(".ok").focus()
- },
-
- advance: function(e){
- e && e.preventDefault()
- this.hide()
- this.callback && this.callback()
- this.callback = null
- }
+ events: {
+ "click .ok": "advance",
+ "click .close": "advance",
+ },
+
+ alert: function(message, callback){
+ this.$(".errorList").empty().append(message)
+ this.callback = callback
+ this.show()
+ this.$(".ok").focus()
+ },
+
+ advance: function(e){
+ e && e.preventDefault()
+ this.hide()
+ this.callback && this.callback()
+ this.callback = null
+ }
}))
diff --git a/public/assets/javascripts/ui/lib/FormView.js b/public/assets/javascripts/ui/lib/FormView.js
index 17b748a..a952ecb 100644
--- a/public/assets/javascripts/ui/lib/FormView.js
+++ b/public/assets/javascripts/ui/lib/FormView.js
@@ -1,127 +1,138 @@
var FormView = View.extend({
- method: "post",
+ method: "post",
+ useMinotaur: false,
- events: {
- "submit form": "save"
- },
+ events: {
+ "submit form": "save"
+ },
- initialize: function(opt){
- if (opt && opt.parent) {
- this.parent = opt.parent
- }
- this.$form = this.$("form")
- this.$errors = this.$(".errors")
- this.$errorList = this.$(".errorList")
- },
+ initialize: function(opt){
+ if (opt && opt.parent) {
+ this.parent = opt.parent
+ }
+ this.$form = this.$("form")
+ this.$errors = this.$(".errors")
+ this.$errorList = this.$(".errorList")
+ },
- reset: function(){
- this.$("input,textarea").not("[type='submit']").not("[type='hidden']").val("")
- },
-
- showErrors: function(errors){
- if (errors && errors.length) {
- this.$errorList.empty();
- for (var i in errors) {
- this.$errorList.append('<div>' + errors[i] + '</div>');
- }
- this.$errors.css("opacity", 1.0);
- setTimeout(function(){
- this.$errors.show().css("opacity", 1.0);
- }.bind(this), 200)
- }
- },
-
- serialize: function(){
- var fd = new FormData(), hasCSRF = false
-
- this.$("input[name], select[name], textarea[name]").each( function(){
- if (this.type == "file") {
- if (this.files.length > 0) {
- fd.append(this.name, this.files[0]);
- }
- }
- else if (this.type == "password") {
- if (this.value.length > 0) {
- fd.append(this.name, SHA1.hex('lol$' + this.value + '$vvalls'))
- }
- }
- else {
- fd.append(this.name, this.value);
- hasCSRF = hasCSRF || this.name == "_csrf"
- }
- });
-
- if (! hasCSRF) {
+ reset: function(){
+ this.$("input,textarea").not("[type='submit']").not("[type='hidden']").val("")
+ },
+
+ showErrors: function(errors){
+ if (errors && errors.length) {
+ this.$errorList.empty();
+ for (var i in errors) {
+ this.$errorList.append('<div>' + errors[i] + '</div>');
+ }
+ this.$errors.css("opacity", 1.0);
+ setTimeout(function(){
+ this.$errors.show().css("opacity", 1.0);
+ }.bind(this), 200)
+ }
+ },
+
+ serialize: function(){
+ var fd = new FormData(), hasCSRF = false
+
+ this.$("input[name], select[name], textarea[name]").each( function(){
+ if (this.type == "file") {
+ if (this.files.length > 0) {
+ fd.append(this.name, this.files[0]);
+ }
+ }
+ else if (this.type == "password") {
+ if (this.value.length > 0) {
+ fd.append(this.name, SHA1.hex('lol$' + this.value + '$vvalls'))
+ }
+ }
+ else {
+ fd.append(this.name, this.value);
+ hasCSRF = hasCSRF || this.name == "_csrf"
+ }
+ });
+
+ if (! hasCSRF) {
fd.append("_csrf", $("[name=_csrf]").val())
}
-
- return fd
- },
-
- save: function(e, successCallback, errorCallback){
- e && e.preventDefault()
+
+ return fd
+ },
+
+ save: function(e, successCallback, errorCallback){
+ e && e.preventDefault()
- this.$errors.hide().css("opacity", 0.0);
-
- if (this.validate) {
- var errors = this.validate()
- if (errors && errors.length) {
- if (errorCallback) {
- errorCallback(errors)
- }
- else {
+ this.$errors && this.$errors.hide().css("opacity", 0.0);
+
+ if (this.validate) {
+ var errors = this.validate()
+ if (errors && errors.length) {
+ if (errorCallback) {
+ setTimeout(function(){
+ errorCallback(errors)
+ })
+ }
+ else {
this.showErrors(errors)
- }
- return
- }
- }
-
- var action = typeof this.action == "function" ? this.action() : this.action
- if (! action) return
+ }
+ return
+ }
+ }
+ var action = typeof this.action == "function" ? this.action() : this.action
+ if (! action) return
- var request = $.ajax({
- url: action,
- type: this.method,
- data: this.serialize(),
- dataType: "json",
- processData: false,
- contentType: false,
- })
-
- request.done($.proxy(function (response) {
- if (response.error) {
- var errors = []
- for (var key in response.error.errors) {
- errors.push(response.error.errors[key].message);
- }
- if (errorCallback) {
- errorCallback(errors)
- }
- else {
+ var request = $.ajax({
+ url: action,
+ type: this.method,
+ data: this.serialize(),
+ dataType: "json",
+ processData: false,
+ contentType: false,
+ })
+
+ if (this.useMinotaur) {
+ Minotaur.show()
+ }
+
+ request.done($.proxy(function (response) {
+ if (this.useMinotaur) {
+ Minotaur.hide()
+ }
+ if (response.error) {
+ var errors = []
+ for (var key in response.error.errors) {
+ errors.push(response.error.errors[key].message);
+ }
+ if (errorCallback) {
+ errorCallback(errors)
+ }
+ else {
this.showErrors(errors)
- }
- return
- }
- else {
- if (successCallback) {
- successCallback(response)
- }
- if (this.success) {
- this.success(response)
- }
- }
- }, this));
- }
+ }
+ return
+ }
+ else {
+ console.log("ok")
+ if (successCallback) {
+ console.log("use cb")
+ successCallback(response)
+ }
+ if (this.success) {
+ this.success(response)
+ }
+ }
+ }, this));
+ }
})
var ModalFormView = ModalView.extend(FormView.prototype).extend({
- load: function(){
- this.reset()
- this.show()
- }
+ load: function(){
+ this.reset()
+ this.show()
+ }
})
diff --git a/public/assets/javascripts/ui/lib/LabColorPicker.js b/public/assets/javascripts/ui/lib/LabColorPicker.js
new file mode 100644
index 0000000..2c8fb90
--- /dev/null
+++ b/public/assets/javascripts/ui/lib/LabColorPicker.js
@@ -0,0 +1,180 @@
+var LabColorPicker = function (parent, w, h) {
+ var base = this
+ var canvas = this.canvas = document.createElement('canvas')
+ canvas.width = w
+ canvas.height = h
+ var ctx = this.ctx = canvas.getContext('2d-lodpi')
+// canvas.className = "colorPicker"
+// var imageData = ctx.createImageData(w, h)
+// var data = imageData.data
+
+ var cursor = this.cursor = document.createElement("div")
+ cursor.className = "colorPickerCursor"
+
+ var brightnessControl = this.brightness = document.createElement("input")
+ var $brightnessControl = $(brightnessControl)
+ brightnessControl.setAttribute("type", "range")
+ brightnessControl.setAttribute("min", "0")
+ brightnessControl.setAttribute("max", "110")
+ brightnessControl.setAttribute("value", "0")
+
+ var ww = w-1
+ var hh = h-1
+
+ var L_range = [0, 110]
+ var a_range = [-86.185, 98.254]
+ var b_range = [-107.863, 94.482]
+
+ var rgb = [0,0,0]
+
+ var val = 80
+
+ this.mouse = new mouse({
+ el: canvas,
+ down: function(e, cursor){
+ parent.begin()
+ cursor.x.a = -cursor.x.a
+ base.pick(cursor.x.a, cursor.y.a)
+ },
+ drag: function(e, cursor){
+ cursor.x.b = -cursor.x.b
+ base.pick(cursor.x.b, cursor.y.b)
+ },
+ up: function(){
+ parent.finalize()
+ }
+ })
+
+ $brightnessControl.on({
+ "mousedown": function(){ base.beginBrightness() },
+ "input": function(){ base.updateBrightness() },
+ })
+
+ this.setLab = function(Lab) {
+ val = Lab[0]
+ this.paint()
+ var rgb = xyz2rgb(hunterlab2xyz(Lab[0], Lab[1], Lab[2])).map(Math.round)
+ return rgb
+ }
+ this.pick = function(i, j){
+ i = clamp(i, 0, w)
+ j = clamp(j, 0, h)
+ var x = mix( i/ww, a_range[0], a_range[1] )
+ var y = mix( j/hh, b_range[0], b_range[1] )
+ var rgb = xyz2rgb(hunterlab2xyz(val, x, y)).map(Math.round)
+ this.moveCursor(i, j)
+ parent.pickColor( rgb, [val,x,y] )
+ }
+ this.load = function(rgba){
+ var Lab = xyz2hunterlab(rgb2xyz(rgba))
+ var val = clamp( Lab[0], L_range[0], L_range[1] )
+ var x = mix( norm(Lab[1], a_range[0], a_range[1]), 0, ww )
+ var y = mix( norm(Lab[2], b_range[0], b_range[1]), 0, hh )
+
+ this.moveCursor(x,y)
+ this.setLab(Lab)
+ this.setBrightness(Lab)
+
+ return Lab
+ }
+ this.moveCursor = function(x,y){
+ cursor.style.left = x + "px"
+ cursor.style.top = y + "px"
+ }
+ this.paint = function() {
+ val = clamp(val, L_range[0], L_range[1])
+ var imageData = ctx.createImageData(canvas.width, canvas.height)
+ var data = imageData.data
+ var x, y, t, cw = imageData.width, ch = imageData.height
+ var cww = cw-1, chh = ch-1
+ for (var i = 0; i < cw; i++) {
+ for (var j = 0; j < ch; j++) {
+ x = mix( i/cww, a_range[0], a_range[1] )
+ y = mix( j/chh, b_range[0], b_range[1] )
+ t = (j*w + i) * 4
+ rgb = xyz2rgb(hunterlab2xyz(val, x, y))
+ data[t] = Math.round( rgb[0] )
+ data[t+1] = Math.round( rgb[1] )
+ data[t+2] = Math.round( rgb[2] )
+ data[t+3] = 255
+ }
+ }
+ ctx.putImageData(imageData,0,0)
+ }
+
+ this.beginBrightness = function(){
+ parent.begin()
+ $(window).one("mouseup", parent.finalize.bind(parent))
+ }
+ this.updateBrightness = function(){
+ parent.labColor[0] = parseFloat( $brightnessControl.val() )
+ var rgb = base.setLab( parent.labColor )
+ parent.pickColor(rgb, parent.labColor)
+ }
+ this.setBrightness = function(Lab){
+ $brightnessControl.val(Lab[0])
+ }
+
+ function hunterlab2xyz (L,a,b) {
+ var_Y = L / 10
+ var_X = a / 17.5 * L / 10
+ var_Z = b / 7 * L / 10
+
+ Y = Math.pow(var_Y, 2)
+ X = ( var_X + Y ) / 1.02
+ Z = -( var_Z - Y ) / 0.847
+ xyz = [X,Y,Z]
+ }
+ function xyz2rgb(){
+ var var_X = xyz[0] / 100 //X from 0 to 95.047 (Observer = 2°, Illuminant = D65)
+ var var_Y = xyz[1] / 100 //Y from 0 to 100.000
+ var var_Z = xyz[2] / 100 //Z from 0 to 108.883
+
+ var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986
+ var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415
+ var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570
+
+ if ( var_R > 0.0031308 ) var_R = 1.055 * Math.pow( var_R, 1 / 2.4 ) - 0.055
+ else var_R = 12.92 * var_R
+ if ( var_G > 0.0031308 ) var_G = 1.055 * Math.pow( var_G, 1 / 2.4 ) - 0.055
+ else var_G = 12.92 * var_G
+ if ( var_B > 0.0031308 ) var_B = 1.055 * Math.pow( var_B, 1 / 2.4 ) - 0.055
+ else var_B = 12.92 * var_B
+
+ rgb[0] = clamp(var_R * 255, 0, 255)
+ rgb[1] = clamp(var_G * 255, 0, 255)
+ rgb[2] = clamp(var_B * 255, 0, 255)
+ return rgb
+ }
+ function rgb2xyz(RGB){
+ var var_R = ( RGB[0] / 255 ) // R from 0 to 255
+ var var_G = ( RGB[1] / 255 ) // G from 0 to 255
+ var var_B = ( RGB[2] / 255 ) // B from 0 to 255
+
+ if ( var_R > 0.04045 ) var_R = Math.pow( ( var_R + 0.055 ) / 1.055, 2.4)
+ else var_R = var_R / 12.92
+ if ( var_G > 0.04045 ) var_G = Math.pow( ( var_G + 0.055 ) / 1.055, 2.4)
+ else var_G = var_G / 12.92
+ if ( var_B > 0.04045 ) var_B = Math.pow( ( var_B + 0.055 ) / 1.055, 2.4)
+ else var_B = var_B / 12.92
+
+ var_R = var_R * 100
+ var_G = var_G * 100
+ var_B = var_B * 100
+
+ //Observer. = 2°, Illuminant = D65
+ var x = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805
+ var y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722
+ var z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505
+ return [x,y,z]
+ }
+ function xyz2hunterlab (XYZ) {
+ var X = XYZ[0]
+ var Y = XYZ[1] || 1e-6 // otherwise divide-by-zero error when converting rgb(0,0,0)
+ var Z = XYZ[2]
+ var L = 10 * sqrt( Y )
+ var a = 17.5 * ( ( ( 1.02 * X ) - Y ) / sqrt( Y ) )
+ var b = 7 * ( ( Y - ( 0.847 * Z ) ) / sqrt( Y ) )
+ return [L,a,b]
+ }
+}
diff --git a/public/assets/javascripts/ui/lib/ModalView.js b/public/assets/javascripts/ui/lib/ModalView.js
index d9b518a..e0070ce 100644
--- a/public/assets/javascripts/ui/lib/ModalView.js
+++ b/public/assets/javascripts/ui/lib/ModalView.js
@@ -1,42 +1,53 @@
var ModalView = View.extend({
- events: {
- "click .close": 'close',
- },
-
- initialize: function(opt){
- if (opt && opt.parent) {
- this.parent = opt.parent
- }
- },
-
- usesFileUpload: false,
-
- show: function(){
- $(".mediaDrawer").removeClass("active")
-
- if (! this.usesFileUpload) {
- $(".fileUpload").removeClass("active")
- }
-
- this.$el.addClass("active")
+ events: {
+ "click .close": 'close',
+ },
+
+ initialize: function(opt){
+ if (opt && opt.parent) {
+ this.parent = opt.parent
+ }
+ },
+
+ usesFileUpload: false,
+
+ show: function(){
+ $(".mediaDrawer").removeClass("active")
+ $(".fileUpload").removeClass("active")
+
+ if (this.fixedClose) {
+ $("#fixed_close").addClass("active")
+ $("#fixed_close").bind("click", this.hide.bind(this))
+ }
+
+ this.$el.addClass("active")
$("body").addClass("noOverflow")
- },
+ },
- hide: function(){
+ hide: function(){
// $(".mediaDrawer, .room1").removeClass("active editing");
- this.$el.removeClass("active");
+ if (this.fixedClose) {
+ $("#fixed_close").removeClass("active")
+ $("#fixed_close").unbind("click", this.hide.bind(this))
+ }
+ this.$el.removeClass("active");
$("body").removeClass("noOverflow");
- },
-
- close: function(){
- if (window.isModalView) {
- window.location.pathname = "/"
- }
- else {
- history.pushState(null, document.title, app.router.originalPath)
- this.hide()
- }
- }
+ },
+
+ hideClose: function(){
+ $("#fixed_close").removeClass("active")
+ $("#fixed_close").unbind("click", this.hide.bind(this))
+ },
+
+ close: function(){
+ if (window.isModalView) {
+ window.location.pathname = "/"
+ }
+ else {
+ history.pushState(null, document.title, app.router.originalPath)
+ this.hide()
+ }
+ }
})
diff --git a/public/assets/javascripts/ui/lib/Parser.js b/public/assets/javascripts/ui/lib/Parser.js
index 52c96e6..411f425 100644
--- a/public/assets/javascripts/ui/lib/Parser.js
+++ b/public/assets/javascripts/ui/lib/Parser.js
@@ -5,9 +5,12 @@ var Parser = {
fetch: function(url, done) {
var img = new Image ()
img.onload = function(){
+ if (!img) return
var width = img.naturalWidth, height = img.naturalHeight
img = null
done({
+ url: url,
+ type: "image",
token: "",
thumbnail: "",
title: "",
@@ -32,6 +35,8 @@ var Parser = {
var width = video.videoWidth, height = video.videoHeight
video = null
done({
+ url: url,
+ type: "video",
token: "",
thumbnail: "",
title: "",
@@ -63,6 +68,8 @@ var Parser = {
success: function(result){
var res = result.items[0]
done({
+ url: url,
+ type: "youtube",
token: id,
thumbnail: thumb,
title: res.snippet.title,
@@ -92,6 +99,8 @@ var Parser = {
return
}
done({
+ url: url,
+ type: "vimeo",
token: id,
thumbnail: res.thumbnail_large,
title: res.title,
@@ -103,10 +112,9 @@ var Parser = {
},
tag: function (media) {
// return '<img class="video" type="vimeo" vid="'+media.token+'" src="'+media.thumbnail+'"><span class="playvid">&#9654;</span>';
- return '<div class="video" style="width: ' + media.width + 'px; height: ' + media.height + 'px; overflow: hidden; position: relative;"><iframe frameborder="0" scrolling="no" seamless="seamless" webkitallowfullscreen="webkitAllowFullScreen" mozallowfullscreen="mozallowfullscreen" allowfullscreen="allowfullscreen" id="okplayer" src="http://player.vimeo.com/video/' + media.token + '?api=1&js_api=1&title=0&byline=0&portrait=0&playbar=0&player_id=okplayer&loop=0&autoplay=0" width="' + media.width + '" height="' + media.height + '" style="position: absolute; top: 0px; left: 0px; width: ' + media.width + 'px; height: ' + media.height + 'px;"></iframe></div>'
+ return '<div class="video" style="width: ' + media.width + 'px; height: ' + media.height + 'px; overflow: hidden; position: relative;"><iframe frameborder="0" scrolling="no" seamless="seamless" webkitallowfullscreen="webkitAllowFullScreen" mozallowfullscreen="mozallowfullscreen" allowfullscreen="allowfullscreen" id="okplayer" src="http://player.vimeo.com/video/' + media.token + '?api=1&title=0&byline=0&portrait=0&playbar=0&player_id=okplayer&loop=0&autoplay=0" width="' + media.width + '" height="' + media.height + '" style="position: absolute; top: 0px; left: 0px; width: ' + media.width + 'px; height: ' + media.height + 'px;"></iframe></div>'
}
},
- /*
{
type: 'soundcloud',
regex: /soundcloud.com\/[-a-zA-Z0-9]+\/[-a-zA-Z0-9]+\/?$/i,
@@ -118,26 +126,33 @@ var Parser = {
+ '&client_id='
+ '0673fbe6fc794a7750f680747e863b10',
success: function(result) {
+ // console.log(result)
done({
+ url: url,
+ type: "soundcloud",
token: result.id,
- thumbnail: "",
- title: "",
- width: 100,
- height: 100,
+ thumbnail: result.artwork_url || result.user.avatar_url,
+ title: result.user.username + " - " + result.title,
+ width: 166,
+ height: 166,
})
}
});
},
tag: function (media) {
- return '<iframe width="400" height="166" scrolling="no" frameborder="no"' +
+ return '<iframe width="166" height="166" scrolling="no" frameborder="no"' +
'src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/' + media.token +
'&amp;color=ff6600&amp;auto_play=false&amp;show_artwork=true"></iframe>'
}
- }, {
+ },
+ /*
+ {
type: 'link',
regex: /^http.+/i,
fetch: function(url, done) {
done({
+ url: url,
+ type: "link",
token: "",
thumbnail: "",
title: "",
@@ -152,12 +167,86 @@ var Parser = {
*/
],
+ tumblr: function(url, cb){
+ var domain = url.replace(/^https?:\/\//,"").split("/")[0]
+ if (domain.indexOf(".") == -1) {
+ domain += ".tumblr.com"
+ }
+ $.ajax({
+ type: 'GET',
+ url: "http://" + domain + "/api/read",
+ dataType: "jsonp",
+ data: {
+ format: "json",
+ },
+ success: function(data){
+ var media_list = []
+ var blog = data.tumblelog
+
+ data.posts.forEach(parse)
+ cb(media_list)
+
+ function parse(post){
+ var media, caption, url
+ switch (post.type) {
+ case 'photo':
+ caption = stripHTML(post['photo-caption'])
+ if (post.photos.length) {
+ post.photos.forEach(function(photo){
+ var media = {
+ url: photo['photo-url-1280'],
+ type: "image",
+ token: "",
+ thumbnail: photo['photo-url-500'],
+ description: caption,
+ width: parseInt(photo.width),
+ height: parseInt(photo.height),
+ }
+ media_list.push(media)
+ })
+ }
+ else {
+ media = {
+ url: post['photo-url-1280'],
+ type: "image",
+ token: "",
+ thumbnail: post['photo-url-500'],
+ description: caption,
+ width: parseInt(post.width),
+ height: parseInt(post.height),
+ }
+ media_list.push(media)
+ }
+ break
+ case 'video':
+ url = post['video-source']
+ if (url.indexOf("http") !== 0) { break }
+ if (Parser.lookup.youtube.regex.test(url)) {
+ var id = (url.match(/v=([-_a-zA-Z0-9]{11})/i) || url.match(/youtu.be\/([-_a-zA-Z0-9]{11})/i) || url.match(/embed\/([-_a-zA-Z0-9]{11})/i))[1].split('&')[0];
+ var thumb = "http://i.ytimg.com/vi/" + id + "/hqdefault.jpg"
+ media = {
+ url: post['video-source'],
+ type: "youtube",
+ token: id,
+ thumbnail: thumb,
+ title: stripHTML(post['video-caption']),
+ width: 640,
+ height: 360,
+ }
+ media_list.push(media)
+ }
+ break
+ }
+ }
+// console.log(post)
+ }
+ })
+ },
+
parse: function (url, cb) {
var matched = Parser.integrations.some(function(integration){
if (integration.regex.test(url)) {
integration.fetch(url, function(res){
- res.url = url
- res.type = integration.type
cb(res)
})
return true
@@ -176,6 +265,15 @@ var Parser = {
return ""
},
+ loadImage: function(url, cb, error){
+ if (Parser.lookup.image.regex.test(url)) {
+ Parser.lookup.image.fetch(url, function(media){
+ cb(media)
+ })
+ }
+ else error && error()
+ },
+
thumbnail: function (media) {
return '<img src="' + (media.thumbnail || media.url) + '" class="thumb">';
},
diff --git a/public/assets/javascripts/ui/lib/Router.js b/public/assets/javascripts/ui/lib/Router.js
index 0b6385c..28905b2 100644
--- a/public/assets/javascripts/ui/lib/Router.js
+++ b/public/assets/javascripts/ui/lib/Router.js
@@ -16,6 +16,7 @@ var Router = View.extend({
if (pathname in routes) {
this[this.routes[pathname]](null)
+ return
}
if (path[path.length-1] == null) {
diff --git a/public/assets/javascripts/ui/lib/ToggleableView.js b/public/assets/javascripts/ui/lib/ToggleableView.js
new file mode 100644
index 0000000..371629f
--- /dev/null
+++ b/public/assets/javascripts/ui/lib/ToggleableView.js
@@ -0,0 +1,19 @@
+var ToggleableView = View.extend({
+
+ toggle: function(state){
+ this.$el.toggleClass("active", state)
+ },
+
+ show: function(){
+ this.toggle(true)
+ },
+
+ hide: function(){
+ this.toggle(false)
+ },
+
+ visible: function(){
+ return this.$el.hasClass("active")
+ }
+
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/lib/Toolbar.js b/public/assets/javascripts/ui/lib/Toolbar.js
new file mode 100644
index 0000000..a9ce51c
--- /dev/null
+++ b/public/assets/javascripts/ui/lib/Toolbar.js
@@ -0,0 +1,22 @@
+var Toolbar = Fiber.extend(function(base){
+ var exports = {}
+ exports.init = function(rapper){
+ this.rapper = (typeof rapper == "string") ? $(rapper)[0] : rapper
+ this.tools = {}
+ this.els = {}
+ }
+ exports.add = function(role, fn){
+ var self = this
+ this.tools[role] = fn
+ this.els[role] = $("[data-role=" + role + "]", self.rapper)
+ this.els[role].click(function(){
+ $(".active", self.rapper).removeClass('active')
+ $(this).addClass('active')
+ fn()
+ })
+ }
+ exports.pick = function(role){
+ this.els[role].trigger("click")
+ }
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/javascripts/ui/lib/UploadView.js b/public/assets/javascripts/ui/lib/UploadView.js
index efaa8c9..d1e2b73 100644
--- a/public/assets/javascripts/ui/lib/UploadView.js
+++ b/public/assets/javascripts/ui/lib/UploadView.js
@@ -3,88 +3,94 @@ var UploadView = View.extend({
// define uploadAction
- events: {
- "change .file": "handleFileSelect",
- "submit form": "preventDefault",
- },
-
- initialize: function(){
- this.$file = this.$(".file")
- this.$upload = this.$(".upload-icon")
+ events: {
+ "change [type=file]": "handleFileSelect",
+ "submit form": "preventDefault",
+ },
+
+ initialize: function(){
+ this.$file = this.$("[type=file]")
+ this.$upload = this.$(".upload-icon")
},
beforeUpload: function(){
},
-
+
handleFileSelect: function(e) {
- e.stopPropagation();
- e.preventDefault();
-
- this.beforeUpload()
+ e.stopPropagation();
+ e.preventDefault();
+
+ this.beforeUpload()
- var files = e.dataTransfer ? e.dataTransfer.files : e.target.files;
+ var files = e.dataTransfer ? e.dataTransfer.files : e.target.files;
- for (var i = 0, f; f = files[i]; i++) {
- if ( ! f.type.match('image.*')) {
- continue;
- }
-
- this.getImageDimensions(f)
- }
- },
-
- getImageDimensions: function(f){
- var base = this
-
- this.$upload.addClass('uploading')
+ for (var i = 0, f; f = files[i]; i++) {
+ if ( ! f.type.match('image.*')) {
+ continue;
+ }
+
+ this.getImageDimensions(f)
+ }
+ },
+
+ getImageDimensions: function(f){
+ var base = this
+
+ this.$upload.addClass('uploading')
- var reader = new FileReader();
+ var reader = new FileReader();
- reader.onload = function(e) {
- var image = new Image()
- image.onload = function(){
- var width = image.naturalWidth,
- height = image.naturalHeight
- base.upload(f, width, height)
- }
- image.src = e.target.result
- }
-
- reader.readAsDataURL(f);
- },
-
- upload: function(f, width, height){
- var fd = new FormData()
- fd.append('image', f)
- fd.append('width', width)
- fd.append('height', height)
- fd.append('_csrf', $("[name=_csrf]").val())
-
- if (this.mediaTag) {
- fd.append('tag', this.mediaTag)
- }
+ reader.onload = function(e) {
+ var image = new Image()
+ image.onload = function(){
+ var width = image.naturalWidth,
+ height = image.naturalHeight
+ base.upload(f, width, height)
+ }
+ image.src = e.target.result
+ }
+
+ reader.readAsDataURL(f);
+ },
+
+ upload: function(f, width, height){
+ var fd = new FormData()
+ fd.append('image', f)
+ fd.append('width', width)
+ fd.append('height', height)
+ fd.append('_csrf', $("[name=_csrf]").val())
+
+ if (this.mediaTag) {
+ fd.append('tag', this.mediaTag)
+ }
- var request = $.ajax({
- url: this.uploadAction,
- type: "post",
- data: fd,
- dataType: "json",
- processData: false,
- contentType: false,
- })
- request.done(this.success.bind(this))
- },
-
- success: function(media){
- if (media.error) {
- return
- }
- this.$upload.removeClass('uploading')
- this.add(media)
- },
-
- add: function(media){
- console.log(media)
- },
+ var request = $.ajax({
+ url: this.uploadAction,
+ type: "post",
+ data: fd,
+ dataType: "json",
+ processData: false,
+ contentType: false,
+ })
+ request.done(this.success.bind(this))
+ },
+
+ success: function(media){
+ if (media.error) {
+ // console.log(media.error)
+ this.$upload.removeClass('uploading')
+ this.error(media.error)
+ return
+ }
+ this.$upload.removeClass('uploading')
+ this.add(media)
+ },
+
+ add: function(media){
+ console.log(media)
+ },
+
+ error: function(error){
+ },
})
diff --git a/public/assets/javascripts/ui/lib/View.js b/public/assets/javascripts/ui/lib/View.js
index d94e6db..9a8ab5b 100644
--- a/public/assets/javascripts/ui/lib/View.js
+++ b/public/assets/javascripts/ui/lib/View.js
@@ -1,139 +1,142 @@
var View = (function($, _){
- var View = function(options) {
- this._id = _.uniqueId('view')
- this.type = "view"
- options || (options = {});
- _.extend(this, _.pick(options, viewOptions))
- this._ensureElement()
- this.initialize.apply(this, arguments)
- this.delegateEvents()
- }
+ var View = function(options) {
+ this._id = _.uniqueId('view')
+ this.type = "view"
+ options || (options = {});
+ _.extend(this, _.pick(options, viewOptions))
+ this._ensureElement()
+ this.initialize.apply(this, arguments)
+ this.delegateEvents()
+ }
- var delegateEventSplitter = /^(\S+)\s*(.*)$/;
+ var delegateEventSplitter = /^(\S+)\s*(.*)$/;
- var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
+ var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
- _.extend(View.prototype, {
+ _.extend(View.prototype, {
- // The default `tagName` of a View's element is `"div"`.
- tagName: 'div',
+ // The default `tagName` of a View's element is `"div"`.
+ tagName: 'div',
- $: function(selector) {
- return this.$el.find(selector);
- },
+ $: function(selector) {
+ return this.$el.find(selector);
+ },
- initialize: function(){},
+ initialize: function(){},
- setElement: function(element, delegate) {
- if (this.$el) this.undelegateEvents();
- this.$el = element instanceof $ ? element : $(element);
- this.el = this.$el[0];
- if (delegate !== false) this.delegateEvents();
- return this;
- },
+ setElement: function(element, delegate) {
+ if (this.$el) this.undelegateEvents();
+ this.$el = element instanceof $ ? element : $(element);
+ this.el = this.$el[0];
+ if (delegate !== false) this.delegateEvents();
+ return this;
+ },
- // Set callbacks, where `this.events` is a hash of
- //
- // *{"event selector": "callback"}*
- //
- // {
- // 'mousedown .title': 'edit',
- // 'click .button': 'save',
- // 'click .open': function(e) { ... }
- // }
- //
- // pairs. Callbacks will be bound to the view, with `this` set properly.
- // Uses event delegation for efficiency.
- // Omitting the selector binds the event to `this.el`.
- // This only works for delegate-able events: not `focus`, `blur`, and
- // not `change`, `submit`, and `reset` in Internet Explorer.
- delegateEvents: function(events) {
- if (!(events || (events = _.result(this, 'events')))) return this;
- this.undelegateEvents();
- for (var key in events) {
- var method = events[key];
- if (!_.isFunction(method)) method = this[events[key]];
- if (!method) continue;
+ // Set callbacks, where `this.events` is a hash of
+ //
+ // *{"event selector": "callback"}*
+ //
+ // {
+ // 'mousedown .title': 'edit',
+ // 'click .button': 'save',
+ // 'click .open': function(e) { ... }
+ // }
+ //
+ // pairs. Callbacks will be bound to the view, with `this` set properly.
+ // Uses event delegation for efficiency.
+ // Omitting the selector binds the event to `this.el`.
+ // This only works for delegate-able events: not `focus`, `blur`, and
+ // not `change`, `submit`, and `reset` in Internet Explorer.
+ delegateEvents: function(events) {
+ if (!(events || (events = _.result(this, 'events')))) return this;
+ this.undelegateEvents();
+ for (var key in events) {
+ var method = events[key];
+ if (!_.isFunction(method)) method = this[events[key]];
+ if (!method) continue;
- var match = key.match(delegateEventSplitter);
- var eventName = match[1], selector = match[2];
- method = _.bind(method, this);
- eventName += '.delegateEvents' + this._id;
- if (selector === '') {
- this.$el.on(eventName, method);
- } else {
- this.$el.on(eventName, selector, method);
- }
- }
- return this;
- },
+ var match = key.match(delegateEventSplitter);
+ var eventName = match[1], selector = match[2];
+ method = _.bind(method, this);
+ eventName += '.delegateEvents' + this._id;
+ if (is_mobile && (selector === 'mouseenter' || selector === 'mouseleave')) {
+ continue
+ }
+ else if (selector === '') {
+ this.$el.on(eventName, method);
+ } else {
+ this.$el.on(eventName, selector, method);
+ }
+ }
+ return this;
+ },
- // Clears all callbacks previously bound to the view with `delegateEvents`.
- undelegateEvents: function() {
- this.$el.off('.delegateEvents' + this._id);
- return this;
- },
+ // Clears all callbacks previously bound to the view with `delegateEvents`.
+ undelegateEvents: function() {
+ this.$el.off('.delegateEvents' + this._id);
+ return this;
+ },
- // Ensure that the View has a DOM element to render into.
- // If `this.el` is a string, pass it through `$()`, take the first
- // matching element, and re-assign it to `el`. Otherwise, create
- // an element from the `id`, `className` and `tagName` properties.
- _ensureElement: function() {
- this.setElement(_.result(this, 'el'), false);
- },
-
- preventDefault: function(e){
- e && e.preventDefault()
- },
-
- stopPropagation: function(e){
- e && e.stopPropagation()
- },
+ // Ensure that the View has a DOM element to render into.
+ // If `this.el` is a string, pass it through `$()`, take the first
+ // matching element, and re-assign it to `el`. Otherwise, create
+ // an element from the `id`, `className` and `tagName` properties.
+ _ensureElement: function() {
+ this.setElement(_.result(this, 'el'), false);
+ },
+
+ preventDefault: function(e){
+ e && e.preventDefault()
+ },
+
+ stopPropagation: function(e){
+ e && e.stopPropagation()
+ },
- });
+ });
- var extend = function(protoProps, staticProps) {
- var staticProps = staticProps || {}
- var parent = this;
- var child;
- var childEvents = {};
+ var extend = function(protoProps, staticProps) {
+ var staticProps = staticProps || {}
+ var parent = this;
+ var child;
+ var childEvents = {};
- // The constructor function for the new subclass is either defined by you
- // (the "constructor" property in your `extend` definition), or defaulted
- // by us to simply call the parent's constructor.
- if (protoProps && _.has(protoProps, 'constructor')) {
- child = protoProps.constructor;
- } else {
- child = function(){ return parent.apply(this, arguments); };
- }
+ // The constructor function for the new subclass is either defined by you
+ // (the "constructor" property in your `extend` definition), or defaulted
+ // by us to simply call the parent's constructor.
+ if (protoProps && _.has(protoProps, 'constructor')) {
+ child = protoProps.constructor;
+ } else {
+ child = function(){ return parent.apply(this, arguments); };
+ }
- // Extend events so we can subclass views
- _.extend(childEvents, parent.prototype.events, protoProps.events)
+ // Extend events so we can subclass views
+ _.extend(childEvents, parent.prototype.events, protoProps.events)
- // Add static properties to the constructor function, if supplied.
- _.extend(child, parent, staticProps);
+ // Add static properties to the constructor function, if supplied.
+ _.extend(child, parent, staticProps);
- // Set the prototype chain to inherit from `parent`, without calling
- // `parent`'s constructor function.
- var Surrogate = function(){ this.constructor = child; };
- Surrogate.prototype = parent.prototype;
- child.prototype = new Surrogate;
+ // Set the prototype chain to inherit from `parent`, without calling
+ // `parent`'s constructor function.
+ var Surrogate = function(){ this.constructor = child; };
+ Surrogate.prototype = parent.prototype;
+ child.prototype = new Surrogate;
- // Add prototype properties (instance properties) to the subclass,
- // if supplied.
- if (protoProps) _.extend(child.prototype, protoProps);
+ // Add prototype properties (instance properties) to the subclass,
+ // if supplied.
+ if (protoProps) _.extend(child.prototype, protoProps);
- // Set a convenience property in case the parent's prototype is needed
- // later.
- child.prototype.__super__ = parent.prototype;
- child.prototype.events = childEvents
+ // Set a convenience property in case the parent's prototype is needed
+ // later.
+ child.prototype.__super__ = parent.prototype;
+ child.prototype.events = childEvents
- return child;
- };
+ return child;
+ };
- View.extend = extend;
-
- return View;
+ View.extend = extend;
+
+ return View;
})(jQuery, _)