koa-js 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/koa-js.rb +5 -0
- data/lib/koa-js/engine.rb +4 -0
- data/vendor/assets/javascripts/koa.js +4 -0
- data/vendor/assets/javascripts/koa/koa-legacy-scroll.js +104 -0
- data/vendor/assets/javascripts/koa/koa-model.js +42 -0
- data/vendor/assets/javascripts/koa/koa-touch.js +135 -0
- data/vendor/assets/javascripts/koa/koa-user.js +112 -0
- metadata +50 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e96de711ed97ee24e16c03017b59c8a94ea32d92
|
4
|
+
data.tar.gz: 37d5ac91a4deb413527e93e7ab89a05420e34d2a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: de6d84ecd1b04960e0aabcc2fc14f72e1ef0e7315cb4d8594ad6ee6f5832b65419a7ecb56eab15deb0add54bfe217b572c2ba548c56efb0e4c828114b3857e1a
|
7
|
+
data.tar.gz: 00978ccf229d21d97d2920f08cf24a1b591ac805351666800b20ac975c900d0dafc526749b1a8ee3210e117e761c842d8751720e52b85a2bfec63c0edb946edc
|
data/lib/koa-js.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
|
2
|
+
function KOALegacyScroll (page, div_id, bottomScrollPadding) {
|
3
|
+
this.bottomScrollPadding = bottomScrollPadding || 0;
|
4
|
+
this.needsConfig = true;
|
5
|
+
this.div_id = div_id;
|
6
|
+
this.wrapper_id = div_id+"_wrap";
|
7
|
+
this.page = page;
|
8
|
+
|
9
|
+
$(this.page).find(this.div_id).off();
|
10
|
+
|
11
|
+
var _this = this;
|
12
|
+
$(this.page).find(this.div_id).on('touchstart', function (event) { _this.touchStart(event); });
|
13
|
+
$(this.page).find(this.div_id).on('touchmove', function (event) { _this.touchMoved(event); });
|
14
|
+
}
|
15
|
+
|
16
|
+
KOALegacyScroll.prototype.touchStart = function (event) {
|
17
|
+
if(this.needsConfig) { this.config(); }
|
18
|
+
this.startScrollTouches = event.touches[0];
|
19
|
+
this.startScrollOffset = parseFloat($(this.div_id).css('top').replace("px", ""));
|
20
|
+
}
|
21
|
+
|
22
|
+
KOALegacyScroll.prototype.touchMoved = function (event) {
|
23
|
+
var offsetAmount = (event.touches[0].screenY - this.startScrollTouches.screenY) ;
|
24
|
+
offsetAmount += this.startScrollOffset;
|
25
|
+
if (offsetAmount > 0) {
|
26
|
+
offsetAmount = 0;
|
27
|
+
}
|
28
|
+
if (offsetAmount < this.maxYOffset) {
|
29
|
+
offsetAmount = this.maxYOffset;
|
30
|
+
}
|
31
|
+
console.log(offsetAmount, this.maxYOffset);
|
32
|
+
// var currentTop = $(this.div_id).css('top').replace("px", "");
|
33
|
+
$(this.div_id).css({"top": offsetAmount+'px'});
|
34
|
+
}
|
35
|
+
KOALegacyScroll.prototype.config = function (event) {
|
36
|
+
console.log('config', this.needsConfig);
|
37
|
+
this.needsConfig = false;
|
38
|
+
var content = $(this.page).find(this.div_id);
|
39
|
+
content.wrap("<div id='"+this.wrapper_id.replace("#","") +"'>");
|
40
|
+
|
41
|
+
var wrapper = $(this.page).find(this.wrapper_id);
|
42
|
+
|
43
|
+
var clone = $(this.page).find(this.div_id).clone().attr("id", false)
|
44
|
+
.css({"visibility":"hidden",
|
45
|
+
"display":"block",
|
46
|
+
"position":"absolute",
|
47
|
+
"height": "auto"});
|
48
|
+
$("body").append(clone);
|
49
|
+
this.contentHeight = clone.height();
|
50
|
+
// this.maxYOffset = -1 * ((content.height() - this.contentHeight) - this.bottomScrollPadding);
|
51
|
+
var top = (content.offset().top + window.screenY) / window.devicePixelRatio ;
|
52
|
+
|
53
|
+
console.log("vp and top" , this.getViewportHeight(), top) ;
|
54
|
+
var windowPosition = this.getViewportHeight() - top ;
|
55
|
+
|
56
|
+
console.log(windowPosition);
|
57
|
+
this.maxYOffset = 0 - content.height() - this.bottomScrollPadding + windowPosition;
|
58
|
+
console.log(this.contentHeight, content.height(), this.maxYOffset);
|
59
|
+
|
60
|
+
wrapper.css({"position":"absolute",
|
61
|
+
"overflow":"hidden",
|
62
|
+
"top":content.css("top"),
|
63
|
+
"width" : content.width()+"px",
|
64
|
+
"height" : content.height()+"px" });
|
65
|
+
|
66
|
+
content.css({"overflow":"visible",
|
67
|
+
"overflow-y":"visible",
|
68
|
+
"top" : "0",
|
69
|
+
"height" : "auto",
|
70
|
+
"float" :"left" ,
|
71
|
+
});
|
72
|
+
|
73
|
+
wrapper.css({"height" : content.height()+"px"});
|
74
|
+
// this.maxYOffset = 0 - this.contentHeight + content.height() - this.bottomScrollPadding;
|
75
|
+
clone.remove();
|
76
|
+
|
77
|
+
|
78
|
+
}
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
KOALegacyScroll.prototype.getViewportHeight = function () {
|
83
|
+
|
84
|
+
var viewPortHeight;
|
85
|
+
|
86
|
+
// the more standards compliant browsers (mozilla/netscape/opera/IE7) use window.innerWidth and window.innerHeight
|
87
|
+
if (typeof window.innerWidth != 'undefined') {
|
88
|
+
viewPortHeight = window.innerHeight
|
89
|
+
}
|
90
|
+
|
91
|
+
// IE6 in standards compliant mode (i.e. with a valid doctype as the first line in the document)
|
92
|
+
else if (typeof document.documentElement != 'undefined'
|
93
|
+
&& typeof document.documentElement.clientWidth !=
|
94
|
+
'undefined' && document.documentElement.clientWidth != 0) {
|
95
|
+
viewPortHeight = document.documentElement.clientHeight
|
96
|
+
}
|
97
|
+
|
98
|
+
// older versions of IE
|
99
|
+
else {
|
100
|
+
viewPortHeight = document.getElementsByTagName('body')[0].clientHeight
|
101
|
+
}
|
102
|
+
console.log('vp height', viewPortHeight);
|
103
|
+
return viewPortHeight;
|
104
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
function KOAModel() {}
|
2
|
+
$.extend(KOAModel, {
|
3
|
+
relationships: {},
|
4
|
+
|
5
|
+
extend: function(def) {
|
6
|
+
def = def || {};
|
7
|
+
def.instance = def.instance || {};
|
8
|
+
def.klass = def.klass || {};
|
9
|
+
var klass = function(data) {
|
10
|
+
this.synthesize(data);
|
11
|
+
};
|
12
|
+
$.extend(klass, this, def.klass);
|
13
|
+
$.extend(klass.prototype, this.prototype, def.instance);
|
14
|
+
return klass;
|
15
|
+
}
|
16
|
+
});
|
17
|
+
|
18
|
+
|
19
|
+
$.extend(KOAModel.prototype, {
|
20
|
+
serialize: function() {
|
21
|
+
var obj = {};
|
22
|
+
for(var i in this) {
|
23
|
+
if(i.indexOf("_") == 0) continue;
|
24
|
+
if(this[i] == undefined || this[i] == null) continue;
|
25
|
+
if(typeof this[i] == "function") continue;
|
26
|
+
obj[i] = this[i];
|
27
|
+
}
|
28
|
+
return obj;
|
29
|
+
},
|
30
|
+
|
31
|
+
synthesize: function(obj) {
|
32
|
+
for(var i in obj) {
|
33
|
+
var ref = i.replace(/([A-Z])/g,"_$1").toLowerCase();
|
34
|
+
if(this.constructor.relationships[ref] != undefined) {
|
35
|
+
var klass = this.constructor.relationships[ref];
|
36
|
+
this[ref] = new window[klass](obj[i]);
|
37
|
+
} else {
|
38
|
+
this[ref] = obj[i];
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
});
|
@@ -0,0 +1,135 @@
|
|
1
|
+
// Zepto.js
|
2
|
+
// (c) 2010-2012 Thomas Fuchs
|
3
|
+
// Zepto.js may be freely distributed under the MIT license.
|
4
|
+
|
5
|
+
;(function($){
|
6
|
+
var touch = {},
|
7
|
+
touchTimeout, tapTimeout, swipeTimeout,
|
8
|
+
longTapDelay = 750, longTapTimeout
|
9
|
+
|
10
|
+
function parentIfText(node) {
|
11
|
+
return 'tagName' in node ? node : node.parentNode
|
12
|
+
}
|
13
|
+
|
14
|
+
function swipeDirection(x1, x2, y1, y2) {
|
15
|
+
var xDelta = Math.abs(x1 - x2), yDelta = Math.abs(y1 - y2)
|
16
|
+
return xDelta >= yDelta ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
|
17
|
+
}
|
18
|
+
|
19
|
+
function longTap() {
|
20
|
+
longTapTimeout = null
|
21
|
+
if (touch.last) {
|
22
|
+
touch.el.trigger('longTap')
|
23
|
+
touch = {}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
function cancelLongTap() {
|
28
|
+
if (longTapTimeout) clearTimeout(longTapTimeout)
|
29
|
+
longTapTimeout = null
|
30
|
+
}
|
31
|
+
|
32
|
+
function cancelAll() {
|
33
|
+
if (touchTimeout) clearTimeout(touchTimeout)
|
34
|
+
if (tapTimeout) clearTimeout(tapTimeout)
|
35
|
+
if (swipeTimeout) clearTimeout(swipeTimeout)
|
36
|
+
if (longTapTimeout) clearTimeout(longTapTimeout)
|
37
|
+
touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null
|
38
|
+
touch = {}
|
39
|
+
}
|
40
|
+
|
41
|
+
$(document).ready(function(){
|
42
|
+
var now, delta
|
43
|
+
|
44
|
+
$(document.body)
|
45
|
+
.bind('touchstart', function(e){
|
46
|
+
now = Date.now()
|
47
|
+
delta = now - (touch.last || now)
|
48
|
+
touch.el = $(parentIfText(e.touches[0].target))
|
49
|
+
touchTimeout && clearTimeout(touchTimeout)
|
50
|
+
touch.x1 = e.touches[0].pageX
|
51
|
+
touch.y1 = e.touches[0].pageY
|
52
|
+
if (delta > 0 && delta <= 250) touch.isDoubleTap = true
|
53
|
+
touch.last = now
|
54
|
+
longTapTimeout = setTimeout(longTap, longTapDelay)
|
55
|
+
})
|
56
|
+
.bind('touchmove', function(e){
|
57
|
+
cancelLongTap()
|
58
|
+
touch.x2 = e.touches[0].pageX
|
59
|
+
touch.y2 = e.touches[0].pageY
|
60
|
+
if (Math.abs(touch.x1 - touch.x2) > 50)
|
61
|
+
e.preventDefault()
|
62
|
+
})
|
63
|
+
.bind('touchend', function(e){
|
64
|
+
cancelLongTap()
|
65
|
+
|
66
|
+
// swipe
|
67
|
+
if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) ||
|
68
|
+
(touch.y2 && Math.abs(touch.y1 - touch.y2) > 30))
|
69
|
+
|
70
|
+
swipeTimeout = setTimeout(function() {
|
71
|
+
touch.el.trigger('swipe')
|
72
|
+
touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))
|
73
|
+
touch = {}
|
74
|
+
}, 0)
|
75
|
+
|
76
|
+
// normal tap
|
77
|
+
else if ('last' in touch)
|
78
|
+
|
79
|
+
// delay by one tick so we can cancel the 'tap' event if 'scroll' fires
|
80
|
+
// ('tap' fires before 'scroll')
|
81
|
+
tapTimeout = setTimeout(function() {
|
82
|
+
|
83
|
+
// trigger universal 'tap' with the option to cancelTouch()
|
84
|
+
// (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
|
85
|
+
var event = $.Event('tap')
|
86
|
+
event.cancelTouch = cancelAll
|
87
|
+
touch.el.trigger(event)
|
88
|
+
|
89
|
+
// trigger double tap immediately
|
90
|
+
if (touch.isDoubleTap) {
|
91
|
+
touch.el.trigger('doubleTap')
|
92
|
+
touch = {}
|
93
|
+
}
|
94
|
+
|
95
|
+
// trigger single tap after 250ms of inactivity
|
96
|
+
else {
|
97
|
+
touchTimeout = setTimeout(function(){
|
98
|
+
touchTimeout = null
|
99
|
+
touch.el.trigger('singleTap')
|
100
|
+
touch = {}
|
101
|
+
}, 250)
|
102
|
+
}
|
103
|
+
|
104
|
+
}, 0)
|
105
|
+
|
106
|
+
})
|
107
|
+
.bind('touchcancel', cancelAll);
|
108
|
+
|
109
|
+
function isTouchDevice(){
|
110
|
+
return 'ontouchstart' in window // works on most browsers
|
111
|
+
|| 'onmsgesturechange' in window; // works on ie10
|
112
|
+
};
|
113
|
+
function tapClick(e) {
|
114
|
+
var event = $.Event('tapClick');
|
115
|
+
event.cancelTouch = cancelAll;
|
116
|
+
if(e.touches) {
|
117
|
+
$(parentIfText(e.touches[0].target)).trigger(event);
|
118
|
+
} else {
|
119
|
+
$(parentIfText(e.target)).trigger(event);
|
120
|
+
}
|
121
|
+
}
|
122
|
+
if(isTouchDevice()) {
|
123
|
+
$(document.body).bind('tap', tapClick);
|
124
|
+
} else {
|
125
|
+
$(document.body).bind('click', tapClick);
|
126
|
+
}
|
127
|
+
|
128
|
+
$(window).bind('scroll', cancelAll);
|
129
|
+
$(window).bind('scroll', function(){ setTimeout(cancelAll,0); });
|
130
|
+
})
|
131
|
+
|
132
|
+
;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap','tapClick'].forEach(function(m){
|
133
|
+
$.fn[m] = function(callback){ return this.bind(m, callback) }
|
134
|
+
})
|
135
|
+
})(Zepto)
|
@@ -0,0 +1,112 @@
|
|
1
|
+
var KOAUser = KOAModel.extend({
|
2
|
+
klass: {
|
3
|
+
callbacks: [],
|
4
|
+
getting_user: false,
|
5
|
+
map: {
|
6
|
+
firstName: "first_name",
|
7
|
+
lastName: "last_name",
|
8
|
+
fullName: "full_name"
|
9
|
+
},
|
10
|
+
|
11
|
+
getPermittedUser: function(cb) {
|
12
|
+
if(cards.kik.hasPermission()) {
|
13
|
+
return this.getUser(cb);
|
14
|
+
} else {
|
15
|
+
cb(Errors.KikPermissionNotReceived);
|
16
|
+
}
|
17
|
+
},
|
18
|
+
|
19
|
+
getUser: function(cb) {
|
20
|
+
if(this.loggedInUser && this.loggedInUser.id) {
|
21
|
+
return cb(null, this.loggedInUser);
|
22
|
+
}
|
23
|
+
this.callbacks.push(cb);
|
24
|
+
if(this.getting_user) return;
|
25
|
+
this.getting_user = true;
|
26
|
+
var _this = this;
|
27
|
+
this.getKikUser(function(err, user) {
|
28
|
+
if(err) {
|
29
|
+
return _this.callbackUser(err, null);
|
30
|
+
}
|
31
|
+
user.login(function(err, user) {
|
32
|
+
_this.callbackUser(err, user);
|
33
|
+
});
|
34
|
+
});
|
35
|
+
},
|
36
|
+
|
37
|
+
callbackUser: function(err, user) {
|
38
|
+
this.getting_user = false;
|
39
|
+
for(var i = 0; i < this.callbacks.length; i++) {
|
40
|
+
this.callbacks[i](err, user);
|
41
|
+
}
|
42
|
+
this.callbacks = [];
|
43
|
+
},
|
44
|
+
|
45
|
+
getKikUser: function(cb) {
|
46
|
+
if(cards.kik && cards.kik.getUser) {
|
47
|
+
var _this = this;
|
48
|
+
cards.kik.getUser(function(user) {
|
49
|
+
if(!user) {
|
50
|
+
return cb(Errors.KikPermissionDenied);
|
51
|
+
}
|
52
|
+
_this.loggedInUser = new KOAUser(user);
|
53
|
+
if(cards.push) {
|
54
|
+
cards.push.getToken(function(token) {
|
55
|
+
if(token){ _this.loggedInUser.push_token = token; }
|
56
|
+
cb(null, _this.loggedInUser);
|
57
|
+
});
|
58
|
+
} else {
|
59
|
+
cb(null, _this.loggedInUser);
|
60
|
+
}
|
61
|
+
});
|
62
|
+
} else {
|
63
|
+
cb(Errors.KikNotSupported);
|
64
|
+
}
|
65
|
+
}
|
66
|
+
},
|
67
|
+
|
68
|
+
instance: {
|
69
|
+
getPic: function() {
|
70
|
+
if(!this.pic || this.pic == "null") {
|
71
|
+
return "/img/default-pic.png";
|
72
|
+
}
|
73
|
+
return this.pic;
|
74
|
+
},
|
75
|
+
|
76
|
+
getThumbnail: function() {
|
77
|
+
if(!this.thumbnail || this.thumbnail == "null") {
|
78
|
+
return "/img/default-avatar.png";
|
79
|
+
}
|
80
|
+
return this.thumbnail;
|
81
|
+
},
|
82
|
+
|
83
|
+
login: function(cb) {
|
84
|
+
var _this = this;
|
85
|
+
if(location.href.match(/https/i)) {
|
86
|
+
cards.kik.sign("login", function(signedData, username, host) {
|
87
|
+
if(!signedData) {
|
88
|
+
cb("Failed to sign data");
|
89
|
+
return;
|
90
|
+
}
|
91
|
+
API.login(_this, signedData, host, function(err, user) {
|
92
|
+
if(err) {
|
93
|
+
return cb(err);
|
94
|
+
}
|
95
|
+
_this.id = user.id;
|
96
|
+
_this.token = user.token;
|
97
|
+
cb(null, _this);
|
98
|
+
});
|
99
|
+
});
|
100
|
+
} else {
|
101
|
+
API.login(this, "", "", function(err, user) {
|
102
|
+
if(err) {
|
103
|
+
return cb(err);
|
104
|
+
}
|
105
|
+
_this.id = user.id;
|
106
|
+
_this.token = user.token;
|
107
|
+
cb(null, _this);
|
108
|
+
});
|
109
|
+
}
|
110
|
+
}
|
111
|
+
}
|
112
|
+
});
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: koa-js
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eric Rykwalder
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-10-17 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: JS Libraries for KOA
|
14
|
+
email: eric@albumatic.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- vendor/assets/javascripts/koa/koa-legacy-scroll.js
|
20
|
+
- vendor/assets/javascripts/koa/koa-model.js
|
21
|
+
- vendor/assets/javascripts/koa/koa-touch.js
|
22
|
+
- vendor/assets/javascripts/koa/koa-user.js
|
23
|
+
- vendor/assets/javascripts/koa.js
|
24
|
+
- lib/koa-js/engine.rb
|
25
|
+
- lib/koa-js.rb
|
26
|
+
homepage: http://github.com/albumatic
|
27
|
+
licenses:
|
28
|
+
- MIT
|
29
|
+
metadata: {}
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubyforge_project:
|
46
|
+
rubygems_version: 2.0.5
|
47
|
+
signing_key:
|
48
|
+
specification_version: 4
|
49
|
+
summary: KOA js libs
|
50
|
+
test_files: []
|