showoff 0.1.4 → 0.2.0

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.
@@ -0,0 +1,201 @@
1
+
2
+ (function($){
3
+
4
+ $.ws = {
5
+
6
+ //==========================================================
7
+ // jQuery plugin jquery.ws.js
8
+ // for Web Sockets
9
+ // need Browser Chrome4.0.249.0+
10
+ // Demo http://bloga.jp/ws/jq/
11
+ // serverside sample @see http://blog.livedoor.jp/kotesaki/archives/1355651.html
12
+
13
+ name : "ws",
14
+ version : "0.3-noenc-pre",
15
+ demo : "http://bloga.jp/ws/jq/conn/b1.htm",
16
+ author : "Toshiro Takahashi",
17
+ lisence : "same as jQuery @see http://docs.jquery.com/Licensing",
18
+ update : 'http://jsgt.org/lib/jquery/plugin/ws/update.txt',
19
+ ver : '<span class="wsVersion" style="color:#aaa"></span><script>'
20
+ + 'jQuery(function($){ $(".wsVersion").html("version:ws-"+$.ws.version) })'
21
+ + '</script>',
22
+
23
+ //Default settings
24
+ wsSettings: {
25
+ url : "ws://"+location.host,
26
+ data : null,//The data which transmit a message
27
+ onopen : function(e){},//callback on opened.
28
+ onmessage : function(msg,wsObject){},//callback on received
29
+ onclose : function(){},//callback on cloased
30
+ hbStr : "Heartbeat",//if null then no Heartbeat
31
+ hbinterval : 60000,//dafault 60sec, min=5000
32
+ onheartbeat: function(){}//callback on heartbeatsended
33
+ },
34
+ wsSetup: function( settings ) {
35
+ jQuery.extend( jQuery.ws.wsSettings, settings );
36
+ }
37
+
38
+ //Note: if you want to stop no-support alert dialog,
39
+ //$.ws.wsSetup({nonosupportmsg:true});
40
+ };
41
+
42
+ /*
43
+ //==========================================================
44
+ // Method
45
+ // Basic Method of this pulgin for Web Sockets
46
+
47
+ $.conn( settings )
48
+
49
+ */
50
+ $.extend($.ws ,{
51
+
52
+ conn : function( s ){
53
+
54
+ s = $.extend(true, s, $.extend(true, {}, $.ws.wsSettings, s));
55
+
56
+ if ("WebSocket" in window) {
57
+
58
+ var url=s.url ,
59
+ //WS Object
60
+ wsoj = new WebSocket( url ) ,
61
+ data = s.data ,
62
+ //Heartbeat
63
+ _MIN_HBINTERVAL=5000,
64
+ _INI_HBINTERVAL=60000,
65
+ hbtimer=null,
66
+ hbStr = (s.hbStr===null)?null:(typeof s.hbStr==='string')?s.hbStr:'Heartbeat',
67
+ hbinterval = (typeof s.hbinterval==='number')?
68
+ (s.hbinterval>=_MIN_HBINTERVAL)?s.hbinterval:_INI_HBINTERVAL
69
+ :_INI_HBINTERVAL;
70
+
71
+ //WS Events bind
72
+ $(wsoj)
73
+ .bind("open",function(e){
74
+ if(s.onopen){ s.onopen(e); } ;
75
+ if(s.hbStr!==null){
76
+ hbtimer = setInterval(function(){
77
+ $(wsoj).wssend(hbStr);
78
+ if(wsoj.onheartbeat){wsoj.onheartbeat(wsoj)}
79
+ }, hbinterval);
80
+ }
81
+ })
82
+ .bind("message",function(e){
83
+ if(s.onmessage){
84
+ s.onmessage(
85
+ e.originalEvent.data
86
+ .replace(/<script(.|\s)*?\/script>/g, ""),
87
+ wsoj
88
+ );
89
+ }
90
+ })
91
+ .bind("close",function(){
92
+ if(s.onclose){
93
+ s.onclose();
94
+ }
95
+ if(hbtimer) {
96
+ clearInterval(hbtimer);
97
+ hbtimer = null;
98
+ }
99
+ wsoj=null;
100
+ });
101
+
102
+ //Add Event to only Instance for on after Hertbeat
103
+ if(s.hbStr!==null){
104
+ wsoj.onheartbeat=function(woj){
105
+ s.onheartbeat(woj);
106
+ }
107
+ }
108
+
109
+ //WS send
110
+ $(wsoj).wssend(data);
111
+
112
+ //WS auto cloase
113
+ $(window)
114
+ .bind("unload",function(e){
115
+ wsoj.close();wsoj=null;
116
+ });
117
+
118
+ return wsoj;
119
+
120
+ } else {
121
+ //no support, message once.
122
+ if(!$.ws.nosupport){
123
+ if(!s.nonosupportmsg)
124
+ alert("no support, please use Chrome4 (v 4.0.238.0 +) or \n Safari nightly");
125
+ $.ws.nosupport=true;
126
+ }
127
+ }
128
+ }
129
+
130
+ });
131
+
132
+ /*
133
+ //==========================================================
134
+ // Method
135
+ // Sub Methods for Web Sockets
136
+
137
+ $(Selectors).wsload( url, data, fn )
138
+ $(Selectors).wssend(data)
139
+ $(Selectors).wsclose()
140
+
141
+ */
142
+ $.fn.extend({
143
+
144
+ //like $(Selectors).load() Some codes from jQuery1.3.2
145
+ wsload : function( url, data, fn ){
146
+
147
+ var off = url.indexOf(" ");
148
+ if ( off >= 0 ) {
149
+ var selector = url.slice(off, url.length);
150
+ url = url.slice(0, off);
151
+ }
152
+
153
+ if ( data )
154
+ if ( $.isFunction( data ) ) {
155
+ fn = data;
156
+ data = null;
157
+ } else if( typeof data === "object" ) {
158
+ data = $.param( data );
159
+ }
160
+ var self = this;
161
+
162
+ $.ws.conn({
163
+ url : url,
164
+ data : data,
165
+ onmessage : function(msg, wsoj){
166
+ if ( wsoj.readyState == wsoj.OPEN )
167
+ self.html( selector ?
168
+ $("<div/>")
169
+ .append(msg)
170
+ .find(selector) :
171
+ msg );
172
+
173
+ if( fn )
174
+ self.each( fn, [msg, wsoj.readyState, wsoj] );
175
+ }
176
+ });
177
+
178
+ return this;
179
+ },
180
+
181
+ //Send to WS Server $(webSocketOj).wssend(data)
182
+ wssend : function(data){
183
+ var oj=this[0];
184
+ if(typeof oj!=="object" && oj.toString()!=="[object WebSocket]"){return this;}
185
+ if(data){
186
+ oj.send(data);
187
+ }
188
+ return this;
189
+ },
190
+
191
+ //Close Web Sockets
192
+ wsclose : function(){
193
+ var oj=this[0];
194
+ if(typeof oj!=="object" && oj.toString()!=="[object WebSocket]"){return this;}
195
+ oj.close();
196
+ oj=null;
197
+ return this;
198
+ }
199
+ });
200
+
201
+ })(jQuery)
@@ -0,0 +1,80 @@
1
+ //alert($.uuid('c-'))
2
+ //alert($.uuid('p-'))
3
+ //$.ws.conn({
4
+ // url : 'ws://localhost:3840/connect?to=master&id=client',
5
+ // onopen : function () {
6
+ // console.log('connected');
7
+ // },
8
+ // onmessage : function (data) {
9
+ // console.log("received: " + data)
10
+ // if(data == 'next') {
11
+ // nextStep()
12
+ // } else if(data == 'prev') {
13
+ // prevStep()
14
+ // } else if(data.match(/^\d+$/)) {
15
+ // gotoSlide(data)
16
+ // }
17
+ // },
18
+ // onclose : function (event) {
19
+ // console.log('disconnected');
20
+ // }
21
+ //})
22
+
23
+ (function($) {
24
+ var client = ShowOff.Client = function() {
25
+ this.id = $.cookie('showoff-client-id')
26
+ if(!this.id) {
27
+ this.id = $.uuid('c-')
28
+ $.cookie('showoff-client-id', this.id)
29
+ }
30
+ this.master = false;
31
+ }
32
+
33
+ // a no-op until the client is connected
34
+ client.send = client.sendToClients = function() {}
35
+
36
+ client.create = function() {
37
+ ShowOff.Client = new ShowOff.Client();
38
+ return ShowOff.Client;
39
+ }
40
+
41
+ client.prototype.watchPresentation = function(host, port, presentationId) {
42
+ var url = 'ws://' + host + ':' + port + '/connect?to=' + presentationId + '&id=' + this.id;
43
+ var cli = this;
44
+ this.socket = $.ws.conn({
45
+ url : url,
46
+ onmessage : this.onMessage,
47
+ onopen : function () {
48
+ console.log('connected to ' + url);
49
+ },
50
+ onclose : function () {
51
+ console.log('disconnected');
52
+ }
53
+ })
54
+ }
55
+
56
+ client.prototype.onMessage = function(data) {
57
+ var cli = ShowOff.Client;
58
+ console.log("recd: " + data)
59
+ switch(data) {
60
+ case 'master':
61
+ cli.master = true;
62
+ break;
63
+ case 'next':
64
+ nextStep();
65
+ break;
66
+ default:
67
+ if(data.match(/^\d+$/))
68
+ gotoSlide(data);
69
+ }
70
+ }
71
+
72
+ client.prototype.sendToClients = function(data) {
73
+ if(!this.master) return
74
+ this.send(data)
75
+ }
76
+
77
+ client.prototype.send = function(data) {
78
+ this.socket.send(data);
79
+ }
80
+ })(jQuery)
data/public/js/showoff.js CHANGED
@@ -1,5 +1,7 @@
1
1
  /* ShowOff JS Logic */
2
2
 
3
+ var ShowOff = {};
4
+
3
5
  var preso_started = false
4
6
  var slidenum = 0
5
7
  var slideTotal = 0
@@ -13,6 +15,7 @@ var incrCurr = 0
13
15
  var incrCode = false
14
16
  var debugMode = false
15
17
  var gotoSlidenum = 0
18
+ var shiftKeyActive = false
16
19
 
17
20
 
18
21
  function setupPreso(load_slides, prefix) {
@@ -30,6 +33,7 @@ function setupPreso(load_slides, prefix) {
30
33
 
31
34
  // bind event handlers
32
35
  document.onkeydown = keyDown
36
+ document.onkeyup = keyUp
33
37
  /* window.onresize = resized; */
34
38
  /* window.onscroll = scrolled; */
35
39
  /* window.onunload = unloaded; */
@@ -169,7 +173,11 @@ function showSlide(back_step) {
169
173
  incrSteps = 0
170
174
  }
171
175
 
176
+ $('body').addSwipeEvents().
177
+ bind('swipeleft', swipeLeft).
178
+ bind('swiperight', swipeRight)
172
179
  removeResults()
180
+ ShowOff.Client.sendToClients(slidenum)
173
181
  }
174
182
 
175
183
  function getSlidePercent()
@@ -194,6 +202,12 @@ function determineIncremental()
194
202
  })
195
203
  }
196
204
 
205
+ function prevStep()
206
+ {
207
+ slidenum--
208
+ showSlide(true) // We show the slide fully loaded
209
+ }
210
+
197
211
  function nextStep()
198
212
  {
199
213
  if (incrCurr >= incrSteps) {
@@ -207,9 +221,15 @@ function nextStep()
207
221
  incrElem.eq(incrCurr).show()
208
222
  }
209
223
  incrCurr++
224
+ ShowOff.Client.sendToClients('next')
210
225
  }
211
226
  }
212
227
 
228
+ function prevStep() {
229
+ slidenum--
230
+ showSlide(true) // We show the slide fully loaded
231
+ }
232
+
213
233
  function doDebugStuff()
214
234
  {
215
235
  if (debugMode) {
@@ -232,7 +252,7 @@ function keyDown(event)
232
252
  if (event.ctrlKey || event.altKey || event.metaKey)
233
253
  return true;
234
254
 
235
- debug('key: ' + key)
255
+ debug('keyDown: ' + key)
236
256
 
237
257
  if (key >= 48 && key <= 57) // 0 - 9
238
258
  {
@@ -247,9 +267,14 @@ function keyDown(event)
247
267
  }
248
268
  gotoSlidenum = 0;
249
269
 
270
+ if (key == 16) // shift key
271
+ {
272
+ shiftKeyActive = true;
273
+ }
250
274
  if (key == 32) // space bar
251
275
  {
252
- nextStep()
276
+ if (shiftKeyActive) { prevStep() }
277
+ else { nextStep() }
253
278
  }
254
279
  else if (key == 68) // 'd' for debug
255
280
  {
@@ -258,8 +283,7 @@ function keyDown(event)
258
283
  }
259
284
  else if (key == 37 || key == 33) // Left arrow or page up
260
285
  {
261
- slidenum--
262
- showSlide(true) // We show the slide fully loaded
286
+ prevStep()
263
287
  }
264
288
  else if (key == 39 || key == 34) // Right arrow or page down
265
289
  {
@@ -280,7 +304,7 @@ function keyDown(event)
280
304
  {
281
305
  $('#help').toggle()
282
306
  }
283
- else if (key == 70) // f for footer
307
+ else if (key == 66 || key == 70) // f for footer (also "b" which is what kensington remote "stop" button sends
284
308
  {
285
309
  $('#footer').toggle()
286
310
  }
@@ -291,6 +315,23 @@ function keyDown(event)
291
315
  return true
292
316
  }
293
317
 
318
+ function keyUp(event) {
319
+ var key = event.keyCode;
320
+ debug('keyUp: ' + key);
321
+ if (key == 16) // shift key
322
+ {
323
+ shiftKeyActive = false;
324
+ }
325
+ }
326
+
327
+
328
+ function swipeLeft() {
329
+ prevStep()
330
+ }
331
+
332
+ function swipeRight() {
333
+ nextStep()
334
+ }
294
335
 
295
336
  function ListMenu(s)
296
337
  {
data/views/index.erb CHANGED
@@ -3,29 +3,36 @@
3
3
 
4
4
  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
5
  <head>
6
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
7
+ <title>Presentation</title>
7
8
 
8
- <title>Presentation</title>
9
+ <link rel="stylesheet" href="<%= @asset_path %>/css/reset.css" type="text/css"/>
10
+ <link rel="stylesheet" href="<%= @asset_path %>/css/showoff.css" type="text/css"/>
9
11
 
10
- <link rel="stylesheet" href="<%= @asset_path %>/css/reset.css" type="text/css"/>
11
- <link rel="stylesheet" href="<%= @asset_path %>/css/showoff.css" type="text/css"/>
12
+ <script type="text/javascript" src="<%= @asset_path %>/js/jquery-1.4.min.js"></script>
13
+ <script type="text/javascript" src="<%= @asset_path %>/js/jquery.cycle.all.js"></script>
14
+ <script type="text/javascript" src="<%= @asset_path %>/js/jquery-print.js"></script>
15
+ <script type="text/javascript" src="<%= @asset_path %>/js/jquery.batchImageLoad.js"></script>
12
16
 
13
- <script type="text/javascript" src="<%= @asset_path %>/js/jquery-1.4.min.js"></script>
14
- <script type="text/javascript" src="<%= @asset_path %>/js/jquery.cycle.all.js"></script>
15
- <script type="text/javascript" src="<%= @asset_path %>/js/jquery.batchImageLoad.js"></script>
16
- <script type="text/javascript" src="<%= @asset_path %>/js/jquery-print.js"></script>
17
- <script type="text/javascript" src="<%= @asset_path %>/js/fg.menu.js"></script>
18
- <script type="text/javascript" src="<%= @asset_path %>/js/showoff.js"></script>
19
- <script type="text/javascript" src="<%= @asset_path %>/js/jTypeWriter.js"> </script>
17
+ <script type="text/javascript" src="<%= @asset_path %>/js/jquery.doubletap-0.1.js"></script>
20
18
 
19
+ <script type="text/javascript" src="<%= @asset_path %>/js/jquery.uuid.js"></script>
20
+ <script type="text/javascript" src="<%= @asset_path %>/js/jquery.cookie.js"></script>
21
+ <script type="text/javascript" src="<%= @asset_path %>/js/jquery.ws-0.3pre.js"></script>
22
+
23
+ <script type="text/javascript" src="<%= @asset_path %>/js/fg.menu.js"></script>
24
+ <script type="text/javascript" src="<%= @asset_path %>/js/showoff.js"></script>
25
+ <script type="text/javascript" src="<%= @asset_path %>/js/jTypeWriter.js"> </script>
21
26
  <script type="text/javascript" src="<%= @asset_path %>/js/sh_main.min.js"></script>
22
27
 
28
+ <!--script type="text/javascript" src="<%= @asset_path %>/js/showoff.client.js"></script-->
29
+
23
30
  <link type="text/css" href="<%= @asset_path %>/css/fg.menu.css" media="screen" rel="stylesheet" />
24
31
  <link type="text/css" href="<%= @asset_path %>/css/theme/ui.all.css" media="screen" rel="stylesheet" />
25
32
  <link type="text/css" href="<%= @asset_path %>/css/sh_style.css" rel="stylesheet" >
26
33
 
27
34
  <% css_files.each do |css_file| %>
28
- <link rel="stylesheet" href="file/<%= css_file %>" type="text/css"/>
35
+ <link rel="stylesheet" href="file/<%= css_file %>" type="text/css"/>
29
36
  <% end %>
30
37
 
31
38
  <% js_files.each do |js_file| %>
@@ -33,9 +40,11 @@
33
40
  <% end %>
34
41
 
35
42
  <script type="text/javascript">
36
-
37
- $(document).ready(function() {
43
+ $(function(){
38
44
  setupPreso(<%= @slides.nil? ? "true" : "false"%>, '<%= @asset_path %>');
45
+ // experimental showoff web socket support
46
+ // ShowOff.Client.create().
47
+ // watchPresentation('localhost', 3840, 'abc')
39
48
  });
40
49
  </script>
41
50
  </head>
data/views/onepage.erb CHANGED
@@ -4,7 +4,6 @@
4
4
  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
5
  <head>
6
6
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
7
-
8
7
  <title>Presentation</title>
9
8
 
10
9
  <% if @no_js %>
@@ -18,7 +17,7 @@
18
17
  <% end %>
19
18
 
20
19
  <% if !@no_js %>
21
- <%= inline_js(['jquery-1.4.min.js', 'jquery-print.js', 'showoff.js', 'onepage.js', 'sh_main.min.js'], 'public/js') %>
20
+ <%= inline_js(['jquery-1.4.min.js', 'jquery.jswipe.js', 'jquery-print.js', 'showoff.js', 'onepage.js', 'sh_main.min.js'], 'public/js') %>
22
21
  <script type="text/javascript">
23
22
  $(document).ready(function() {
24
23
  setupOnePage()
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: showoff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Chacon
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-03-15 00:00:00 -07:00
12
+ date: 2010-05-04 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -52,6 +52,16 @@ dependencies:
52
52
  - !ruby/object:Gem::Version
53
53
  version: "0"
54
54
  version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: gli
57
+ type: :runtime
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 1.1.0
64
+ version:
55
65
  description: " ShowOff is a Sinatra web app that reads simple configuration files for a\n presentation. It is sort of like a Keynote web app engine. I am using it\n to do all my talks in 2010, because I have a deep hatred in my heart for\n Keynote and yet it is by far the best in the field.\n\n The idea is that you setup your slide files in section subdirectories and\n then startup the showoff server in that directory. It will read in your\n showoff.json file for which sections go in which order and then will give \n you a URL to present from.\n"
56
66
  email: schacon@gmail.com
57
67
  executables:
@@ -61,7 +71,7 @@ extensions: []
61
71
  extra_rdoc_files: []
62
72
 
63
73
  files:
64
- - README.txt
74
+ - README.rdoc
65
75
  - Rakefile
66
76
  - LICENSE
67
77
  - bin/showoff
@@ -76,6 +86,7 @@ files:
76
86
  - public/css/reset.css
77
87
  - public/css/sh_style.css
78
88
  - public/css/showoff.css
89
+ - public/css/spinner_bar.gif
79
90
  - public/css/theme/images/ui-bg_diagonals-small_100_f0efea_40x40.png
80
91
  - public/css/theme/images/ui-bg_flat_35_f0f0f0_40x100.png
81
92
  - public/css/theme/images/ui-bg_glass_55_fcf0ba_1x400.png
@@ -102,11 +113,16 @@ files:
102
113
  - public/css/theme/ui.slider.css
103
114
  - public/css/theme/ui.tabs.css
104
115
  - public/css/theme/ui.theme.css
116
+ - public/favicon.ico
105
117
  - public/js/fg.menu.js
106
118
  - public/js/jquery-1.4.min.js
107
119
  - public/js/jquery-print.js
108
120
  - public/js/jquery.batchImageLoad.js
121
+ - public/js/jquery.cookie.js
109
122
  - public/js/jquery.cycle.all.js
123
+ - public/js/jquery.doubletap-0.1.js
124
+ - public/js/jquery.uuid.js
125
+ - public/js/jquery.ws-0.3pre.js
110
126
  - public/js/jTypeWriter.js
111
127
  - public/js/onepage.js
112
128
  - public/js/sh_lang/sh_bison.min.js
@@ -149,6 +165,7 @@ files:
149
165
  - public/js/sh_lang/sh_xml.min.js
150
166
  - public/js/sh_lang/sh_xorg.min.js
151
167
  - public/js/sh_main.min.js
168
+ - public/js/showoff.client.js
152
169
  - public/js/showoff.js
153
170
  has_rdoc: false
154
171
  homepage: http://github.com/schacon/showoff