Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

EtherCalc: 多人即時
協作試算表

3,064 views

Published on

OSDC.tw 2012 slides for http://ethercalc.org/.

Please see http://ethercalc.tw/ for extra material in Chinese.

Published in: Technology, Sports

EtherCalc: 多人即時
協作試算表

  1. 1. EtherCalc多人即時協作試算表ethercalc.tw
  2. 2. 僅代表個人立場
  3. 3. 僅代表個人立場(但難免會有業配)
  4. 4. 限於時間只講故事不講程式
  5. 5. 限於時間 概念只講故事不講程式
  6. 6. ethercalc.org‣ npm install -g ethercalc‣ ethercalc Please connect to: http://0:8000/ nodejs.org/#download
  7. 7. ⟪開源應用架構⟫aosabook.org aosa.tw
  8. 8. 緣起
  9. 9. VisiCalc, 1979Dan Bricklin
  10. 10. 哈佛商學院, 1977
  11. 11. 哈佛商學院, 1977
  12. 12. 哈佛商學院, 1977
  13. 13. 哈佛商學院, 1977
  14. 14. 哈佛商學院, 1977
  15. 15. 最初的願景
  16. 16. 最初的願景 Alto 工作站
  17. 17. 最初的願景 Alto 工作站滑鼠計算機
  18. 18. 最初的願景 Alto 工作站滑鼠計算機 頭戴顯示器
  19. 19. 最初的願景 Alto 工作站滑鼠計算機 頭戴顯示器
  20. 20. =SUM( ) 0
  21. 21. 10 =SUM( ) 10 0
  22. 22. 10 20 =SUM( ) 30 10 0
  23. 23. 10 20 30 =SUM( ) 60 30 10 0
  24. 24. 10 20 30 =SUM( ) 60 30 10 0
  25. 25. 1977 → 1978
  26. 26. 1977 → 1978
  27. 27. 1977 → 1978 + Integer BASIC
  28. 28. 1978 → 1979
  29. 29. 1978 → 1979 10 20 30 =SUM( ) 60
  30. 30. 1978 → 1979 A B C D1 10 20 302 =SUM( ) 60
  31. 31. 1978 → 1979 A B C D1 10 20 302 =SUM(A1,B1,C1) 60
  32. 32. 1978 → 1979 A B C D1 10 20 302 =SUM(A1,B1,C1) 60 Bob & Dan
  33. 33. 1978 → 1979 A B C D 1 10 20 30 2 =SUM(A1,B1,C1) 60‣ Dan 持續用 BASIC 寫原型 Bob & Dan
  34. 34. 1978 → 1979 A B C D 1 10 20 30 2 =SUM(A1,B1,C1) 60‣ Dan 持續用 BASIC 寫原型‣ Bob 以組合語言做出成品 Bob & Dan
  35. 35. 1978 → 1979 A B C D 1 10 20 30 2 =SUM(A1,B1,C1) 60‣ Dan 持續用 BASIC 寫原型‣ Bob 以組合語言做出成品‣ 六年內售出 700,000 套 Bob & Dan
  36. 36. 1978 → 1979 A B C D 1 10 20 30 2 =SUM(A1,B1,C1) 60‣ Dan 持續用 BASIC 寫原型‣ Bob 以組合語言做出成品‣ 六年內售出 700,000 套‣ 「殺手級應用」的始祖 Bob & Dan
  37. 37. 1981
  38. 38. 二十年來
  39. 39. 二十年來
  40. 40. 二十年來
  41. 41. 二十年來
  42. 42. 二十年來 始終如一
  43. 43. “打不開”
  44. 44. “打不開”“變亂碼”
  45. 45. “打不開”“變亂碼”“有病毒!”
  46. 46. 維基百科, 2001
  47. 47. 維基百科, 2001
  48. 48. 維基百科, 2001
  49. 49. wikiCalc, 2005
  50. 50. wikiCalc, 2005✓ 支援純文字、HTML、Wiki 語法。
  51. 51. wikiCalc, 2005✓ 支援純文字、HTML、Wiki 語法。✓ 引用其他伺服器上的數值。
  52. 52. wikiCalc, 2005✓ 支援純文字、HTML、Wiki 語法。✓ 引用其他伺服器上的數值。✓ 記錄所有編輯操作,以供稽核紀錄。
  53. 53. wikiCalc, 2005✓ 支援純文字、HTML、Wiki 語法。✓ 引用其他伺服器上的數值。✓ 記錄所有編輯操作,以供稽核紀錄。✓ 保留每個版本,可隨時回復 。
  54. 54. wikiCalc, 2005✓ 支援純文字、HTML、Wiki 語法。✓ 引用其他伺服器上的數值。✓ 記錄所有編輯操作,以供稽核紀錄。✓ 保留每個版本,可隨時回復 。✓ 開放源碼!(GPLv2)。
  55. 55. wikiCalc.pl
  56. 56. wikiCalc.pl 網站./wkcdata/sites/Foo ./wkcdata/sites/Bar ./wkcdata/sites/Baz
  57. 57. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ
  58. 58. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格
  59. 59. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格 A1: 100
  60. 60. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格 A1: 100 A2: =A1*2
  61. 61. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格 A1: 100 B1: =XXX!C1 A2: =A1*2
  62. 62. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格 A1: 100 B1: =XXX!C1 A2: =A1*2
  63. 63. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格 A1: 100 B1: =XXX!C1 A2: =A1*2 B2: =YYY!D2
  64. 64. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格 A1: 100 B1: =XXX!C1 A2: =A1*2 B2: =YYY!D2
  65. 65. wikiCalc.pl 網站 頁面./wkcdata/sites/Foo XXX ./wkcdata/sites/Bar ./wkcdata/sites/Baz YYY ZZZ 儲存格 A1: 100 B1: =XXX!C1 A2: =A1*2 B2: =YYY!D2 跨頁引用
  66. 66. wikiCalc 編輯流程
  67. 67. wikiCalc 編輯流程 A1: 100 A2: =A1*2
  68. 68. wikiCalc 編輯流程 A1: 100 A2: =A1*2
  69. 69. wikiCalc 編輯流程 A1: 100 A2: =A1*2 POST / ajaxsetcell=host:page:A1:300 wikicalc.pl
  70. 70. wikiCalc 編輯流程 A1: 100 A2: =A1*2 POST / ajaxsetcell=host:page:A1:300 wikicalc.pl 200 OK <?xml version="1.0"?> <root><![CDATA[ A1:v:300:300:right:1:1:: A2:f:600:A1*2:right:1:1:: ]]></root>
  71. 71. “載入中…”
  72. 72. “載入中…”
  73. 73. “載入中…”“C100k” 問題
  74. 74. “載入中…”“C100k” 問題
  75. 75. 打掉重練
  76. 76. 打掉重練
  77. 77. SocialCalc, 2006Dan Bricklin Ross Mayfield
  78. 78. 設計目標
  79. 79. 設計目標‣ 用 Javascript 重寫計算引擎。
  80. 80. 設計目標‣ 用 Javascript 重寫計算引擎。‣ 進行編輯操作時提供快速回應。
  81. 81. 設計目標‣ 用 Javascript 重寫計算引擎。‣ 進行編輯操作時提供快速回應。‣ 同時處理十萬個儲存格的能力。
  82. 82. 設計目標‣ 用 Javascript 重寫計算引擎。‣ 進行編輯操作時提供快速回應。‣ 同時處理十萬個儲存格的能力。‣ 加強對各種不同瀏覽器的支援。
  83. 83. 設計目標‣ 用 Javascript 重寫計算引擎。‣ 進行編輯操作時提供快速回應。‣ 同時處理十萬個儲存格的能力。‣ 加強對各種不同瀏覽器的支援。‣ 客戶端稽核紀錄及還原/重作功能。
  84. 84. 系統架構
  85. 85. 系統架構SocialCalc.jsHTTP Server
  86. 86. 系統架構 SocialCalc.jsGET HTTP Server
  87. 87. 系統架構 SocialCalc.jsGET HTTP Server
  88. 88. 系統架構 SocialCalc.jsGET GET HTTP Server
  89. 89. 系統架構 SocialCalc.jsGET GET ($) HTTP Server
  90. 90. 系統架構 SocialCalc.js PUTGET GET ($) HTTP Server
  91. 91. 系統架構 SocialCalc.js PUTGET GET ($) HTTP Server
  92. 92. 指令設計模式
  93. 93. 指令設計模式set A1 value n 42
  94. 94. 指令設計模式set A1 value n 42set A2 formula A1*2
  95. 95. 指令設計模式set A1 value n 42set A2 formula A1*2merge A1:B2cut A3paste A4sort A1:B9 A up B downset sheet defaultcolor blue...
  96. 96. 指令設計模式set A1 value n 42set A2 formula A1*2‣ 異步處理背景計算。
  97. 97. 指令設計模式set A1 value n 42set A2 formula A1*2‣ 異步處理背景計算。‣ 僅需重繪可視區域。
  98. 98. 指令設計模式set A1 value n 42set A2 formula A1*2‣ 異步處理背景計算。‣ 僅需重繪可視區域。‣ 還原重做次數不限。
  99. 99. 指令設計模式set A1 value n 42set A2 formula A1*2‣ 異步處理背景計算。‣ 僅需重繪可視區域。‣ 還原重做次數不限。‣ 鍵盤滑鼠隨時可用!
  100. 100. 指令設計模式set A1 value n 42set A2 formula A1*2‣ 異步處理背景計算。‣ 僅需重繪可視區域。‣ 還原重做次數不限。‣ 鍵盤滑鼠隨時可用!
  101. 101. “社會化” 試算表
  102. 102. “社會化” 試算表
  103. 103. “社會化” 試算表 評論、按讚、推薦、 標記、分享、嵌入...
  104. 104. 社會物件 人際連結
  105. 105. 社會物件 人際連結
  106. 106. 社會物件 人際連結
  107. 107.
  108. 108. CPAL 通用公共授權
  109. 109. CPAL 通用公共授權 ㊔BSD, MIT
  110. 110. CPAL 通用公共授權 © ㊔BSD, MIT LGPL, MPL
  111. 111. CPAL 通用公共授權 © ++© ㊔BSD, MIT LGPL, MPL GPL
  112. 112. CPAL 通用公共授權 © ++© ㊔BSD, MIT LGPL, MPL GPL “ASP
  113. 113.   ”
  114. 114. CPAL 通用公共授權 © ++© ㊔BSD, MIT LGPL, MPL GPL “ASP
  115. 115.   ” Affero GPL
  116. 116. CPAL 通用公共授權 © ++© ㊔BSD, MIT LGPL, MPL GPL “ASP
  117. 117.   ” CPAL Affero GPL
  118. 118. CPAL 通用公共授權 © ++© ㊔BSD, MIT LGPL, MPL GPL “ASP
  119. 119.   ” CPAL Affero GPL
  120. 120. CPAL 通用公共授權 © ++© ㊔BSD, MIT LGPL, MPL GPL “ASP
  121. 121.   ” CPAL Affero GPL
  122. 122. CPAL 通用公共授權 © ++© ㊔BSD, MIT LGPL, MPL GPL “ASP
  123. 123.   ” CPAL Affero GPL
  124. 124. Sheetnode, 2008Karim Ratib
  125. 125. Sheetnode, 2008 Views + Fields + CCKKarim Ratib
  126. 126. Sheetnode, 2008 Views + Fields + CCK SocialCalc.jsKarim Ratib
  127. 127. Sheetnode, 2008 Views + Fields + CCK SocialCalc.jsKarim Ratib
  128. 128. Sheetnode, 2008 Views + Fields + CCK SocialCalc.jsKarim Ratib
  129. 129. Sheetnode, 2008 Views + Fields + CCK SocialCalc.jsKarim Ratib
  130. 130. OLPC, 2008
  131. 131. OLPC, 2008Luke Closs Dan
  132. 132. Mesh網絡
  133. 133. Manusheel GuptaVijit Singh
  134. 134. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js XoCom.pyManusheel GuptaVijit Singh
  135. 135. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42 XoCom.pyManusheel GuptaVijit Singh
  136. 136. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42 XoCom.py D-Bus + TelepathyManusheel GuptaVijit Singh
  137. 137. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42 XoCom.py D-Bus + Telepathy OLPC MeshManusheel Gupta 網絡廣播Vijit Singh
  138. 138. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42 XoCom.py D-Bus + Telepathy OLPC MeshManusheel Gupta 網絡廣播 D-Bus + Telepathy Gecko/XPCOM SocialCalc.js XoCom.js XoCom.pyVijit Singh SocialCalcActivity.py
  139. 139. SocialCalcActivity.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42 XoCom.py D-Bus + Telepathy OLPC MeshManusheel Gupta 網絡廣播 D-Bus + Telepathy Gecko/XPCOM set A1 value n 42 SocialCalc.js XoCom.js XoCom.pyVijit Singh SocialCalcActivity.py
  140. 140. 很讚,但是...
  141. 141. 很讚,但是...‣ 必須同時開啟試算表。
  142. 142. 很讚,但是...‣ 必須同時開啟試算表。‣ 漏接訊息時無法復原。
  143. 143. 很讚,但是...‣ 必須同時開啟試算表。‣ 漏接訊息時無法復原。‣ 編輯同一格時會衝突。
  144. 144. 很讚,但是...‣ 必須同時開啟試算表。‣ 漏接訊息時無法復原。‣ 編輯同一格時會衝突。‣ 只能在 OLPC 上運行!
  145. 145. YAPC::Tiny, 2009 跳格 Multiplayer SocialCalc 二零零九 唐鳳 字 中英雙宇有字版
  146. 146. EV: 事件驅動
  147. 147. Tatsumaki EV: 事件驅動 @miyagawa
  148. 148. Tatsumaki EV: 事件驅動 Web::Hippie @miyagawa @clkao
  149. 149. Tatsumaki EV: 事件驅動 Web::Hippie Feersum @miyagawa @clkao @stash
  150. 150. WebSocket 同步編輯 multiserver.pl Web::Hippie Plack Feersum EV/libev
  151. 151. WebSocket 同步編輯 SpreadsheetControl multiserver.pl Web::HippieScheduleScheetCommand set A1 value n 2046 Plack RenderSheet Feersum EV/libev
  152. 152. WebSocket 同步編輯 SpreadsheetControl multiserver.pl Web::HippieScheduleScheetCommand set A1 value n 2046 Plack RenderSheet 傳送 Feersum EV/libev
  153. 153. WebSocket 同步編輯 SpreadsheetControl multiserver.plScheduleScheetCommand Web::Hippie 群播 set A1 value n 2046 Plack RenderSheet 傳送 Feersum EV/libev
  154. 154. WebSocket 同步編輯 SpreadsheetControl multiserver.plScheduleScheetCommand Web::Hippie 群播 set A1 value n 2046 Plack ScheduleScheetCommand RenderSheet 傳送 Feersum EV/libev set A1 value n 2046 (isRemote = true) RenderSheet
  155. 155. 新增功能
  156. 156. 新增功能✓ 加入時取得目前狀態。
  157. 157. 新增功能✓ 加入時取得目前狀態。✓ 斷線重連時可以復原。
  158. 158. 新增功能✓ 加入時取得目前狀態。✓ 斷線重連時可以復原。✓ 顯示別人的游標位置。
  159. 159. 新增功能✓ 加入時取得目前狀態。✓ 斷線重連時可以復原。✓ 顯示別人的游標位置。✓ 可以在各平台上運行!
  160. 160. 新增功能✓ 加入時取得目前狀態。✓ 斷線重連時可以復原。✓ 顯示別人的游標位置。✓ 可以在各平台上運行!
  161. 161. 更讚了,但是...
  162. 162. 更讚了,但是...‣ 要相信誰的目前狀態?
  163. 163. 更讚了,但是...‣ 要相信誰的目前狀態?‣ 所有人離線: 資料消失?
  164. 164. 更讚了,但是...‣ 要相信誰的目前狀態?‣ 所有人離線: 資料消失?‣ 一定要有人負責按儲存?
  165. 165. 更讚了,但是...‣ 要相信誰的目前狀態?‣ 所有人離線: 資料消失?‣ 一定要有人負責按儲存?‣ 重新連接: 回播所有指令?
  166. 166. 更讚了,但是...‣ 要相信誰的目前狀態?‣ 所有人離線: 資料消失?‣ 一定要有人負責按儲存?‣ 重新連接: 回播所有指令?
  167. 167. 打掉重練
  168. 168. 打掉重練
  169. 169. YAPC::NA, 2006
  170. 170. YAPC::NA, 2006“I think, but I cannot prove, that bythe next year JavaScript 2.0 willbootstrap itself, complete selfhosting, compile back to JavaScript,and replace Ruby as the Next BigThing in all environments. ”
  171. 171. YAPC::NA, 2006
  172. 172. YAPC::NA, 2006“JavaScript will become the commonbackend for all dynamic languages,and so you can write Perl to run in thebrowser, on the server, and insidedatabases, all with the same set ofdevelopment tools. ”
  173. 173. YAPC::NA, 2006
  174. 174. YAPC::NA, 2006“Because, as we all know,worse is better, so the worstscripting language is doomedto become the best.”
  175. 175. YAPC::NA, 2006“Because, as we all know,worse is better, so the worstscripting language is doomedto become the best.” 劣即是夯
  176. 176. JavaScript: 缺點減少
  177. 177. JavaScript: 缺點減少 CoffeeScript: 標點減半 cs = (js) = js/2 JeremyAshkenas
  178. 178. JavaScript: 缺點減少 CoffeeScript: 標點減半 cs = (js) = js/2 JeremyAshkenas
  179. 179. JavaScript: 缺點減少 CoffeeScript: 標點減半 cs = (js) = js/2 “原 JavaScript 行數: 22k。  重寫過的 CoffeeScript 行數: 5k。  {async, jsdom, zappa, optimist etc}++” JeremyAshkenas
  180. 180. {x,y} = @offset
  181. 181. {x,y} = @offsetvar _ref = this.offset;
  182. 182. {x,y} = @offsetvar _ref = this.offset;var x = _ref.x;
  183. 183. {x,y} = @offsetvar _ref = this.offset;var x = _ref.x;var y = _ref.y;
  184. 184. {x,y} = @offsetvar _ref = this.offset;var x = _ref.x;var y = _ref.y; js2coffee.org
  185. 185. Function::ᵒ = (fun) -
  186. 186. Function::ᵒ = (fun) - (arg) = @ fun arg
  187. 187. Function::ᵒ = (fun) - (arg) = @ fun argf = (x) = x * 2
  188. 188. Function::ᵒ = (fun) - (arg) = @ fun argf = (x) = x * 2g = (x) = x * 3
  189. 189. Function::ᵒ = (fun) - (arg) = @ fun argf = (x) = x * 2g = (x) = x * 3h = f .ᵒ g
  190. 190. Function::ᵒ = (fun) - (arg) = @ fun argf = (x) = x * 2g = (x) = x * 3h = f .ᵒ gh 100 # 600
  191. 191. Function::ᵒ = (fun) - (arg) = @ fun argf = (x) = x * 2g = (x) = x * 3h = f .ᵒ gh 100 # 600
  192. 192. Zappa: Node.js 懶人包 zappajs.org
  193. 193. Zappa: Node.js 懶人包MauriceMachado zappajs.org
  194. 194. Zappa: Node.js 懶人包 “If you can describe it in 495 characters, why on earth shouldMaurice it take 879?”Machado zappajs.org
  195. 195. require(zappa) - @view layout: - html = body = @body @get /: - @render index @view index: - for name, value of { wiki: Wiki to HTML html: HTML to Wiki } form method: post, = p = textarea {name} p = input {type: submit, value}
  196. 196. require(zappa) - @view layout: - html = body = @body @get /: - @render index @view index: - for name, value of { wiki: Wiki to HTML html: HTML to Wiki } form method: post, = p = textarea {name} p = input {type: submit, value}
  197. 197. require(zappa) -@post /: - - @view layout: if @data.wiki? @body html = body = @send w2h @data.wiki @get /: - @render index else if @data.html? @send h2w @data.html @view index: - for name, value of { else redirect / wiki: Wiki to HTML html: HTML to Wiki } form method: post, = p = textarea {name} p = input {type: submit, value}
  198. 198. COSCUP, 2011
  199. 199. COSCUP, 2011
  200. 200. COSCUP, 2011hack
  201. 201.  hack
  202. 202.  hack
  203. 203.  ...
  204. 204. COSCUP, 2011hack
  205. 205.  hack
  206. 206.  hack
  207. 207.  ...
  208. 208. EtherCalc 系統架構
  209. 209. EtherCalc 系統架構 main.coffee sc.coffee Socket.ioSocialCalc.js Express Node.js db.coffee EV/libuv redis.js Zappa
  210. 210. EtherCalc 系統架構 main.coffee sc.coffee Socket.ioSocialCalc.js Express Node.js db.coffee EV/libuv redis.js Zappa Redis(optional)
  211. 211. EtherCalc 系統架構 main.coffee sc.coffee Socket.ioSocialCalc.js Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js Redis(optional)
  212. 212. EtherCalc 系統架構 main.coffee MULTI sc.coffee GET snapshot Socket.io LRANGE logSocialCalc.js EXEC Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js Redis(optional)
  213. 213. EtherCalc 系統架構 main.coffee MULTI sc.coffee GET snapshot Socket.io LRANGE logSocialCalc.js EXEC Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js RPUSH log cmd Redis(optional)
  214. 214. EtherCalc 系統架構 main.coffee MULTI sc.coffee GET snapshot Socket.io LRANGE logSocialCalc.js EXEC Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js RPUSH log cmd Redis(optional)
  215. 215. EtherCalc 系統架構 main.coffee MULTI sc.coffee GET snapshot Socket.io LRANGE logSocialCalc.js EXEC Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js RPUSH log cmd Redis(optional)
  216. 216. EtherCalc 系統架構 main.coffee MULTI sc.coffee GET snapshot Socket.io LRANGE logSocialCalc.js EXEC Express Node.js db.coffee EV/libuv player.coffee redis.js Zappa SocialCalc.js MULTI RPUSH log cmd Redis DEL log(optional) SET snapshot snapshot EXEC
  217. 217. 跨頁即時更新
  218. 218. 跨頁即時更新伺服端
  219. 219. 跨頁即時更新伺 客服 戶端 端
  220. 220. 跨頁即時更新 ask.log: Foo伺 客服 戶端 端
  221. 221. 跨頁即時更新 ask.log: Foo伺 log: Foo,snapshot,log 客服 戶端 端
  222. 222. 跨頁即時更新 ask.log: Foo伺 log: Foo,snapshot,log 客 execute: set A1服 formula Bar!B2 戶端 端
  223. 223. 跨頁即時更新 ask.log: Foo伺 log: Foo,snapshot,log 客 execute: set A1服 formula Bar!B2 ask.recalc: Bar 戶端 端
  224. 224. 跨頁即時更新 ask.log: Foo伺 log: Foo,snapshot,log 客 execute: set A1服 formula Bar!B2 ask.recalc: Bar 戶端 recalc: Bar,snapshot 端
  225. 225. 跨頁即時更新 ask.log: Foo伺 log: Foo,snapshot,log 客 execute: set A1服 formula Bar!B2 ask.recalc: Bar 戶端 recalc: Bar,snapshot 端 recalc: Bar,snapshot
  226. 226. PaaS 遠端建置
  227. 227. PaaS 遠端建置 stackato.yml app.js
  228. 228. PaaS 遠端建置 stackato.yml app.js dotcloud.yml server.js
  229. 229. PaaS 遠端建置 stackato.yml app.js dotcloud.yml server.js server.js
  230. 230. REST 資源界面
  231. 231. REST 資源界面GET /_/pagePUT /_/page
  232. 232. REST 資源界面GET /_/page POST /_/pagePUT /_/page {commands:[…]}
  233. 233. REST 資源界面GET /_/page POST /_/pagePUT /_/page {commands:[…]} GET /_/page/cells/A1 PUT /_/page/cells/A1 GET /_/page/names/range
  234. 234. TODO, 2012
  235. 235. TODO, 2012‣ 內建聊天室、即時共筆
  236. 236. TODO, 2012‣ 內建聊天室、即時共筆‣ 匯出匯入、動態製圖
  237. 237. TODO, 2012‣ 內建聊天室、即時共筆‣ 匯出匯入、動態製圖‣ 與 Drupal 系統整合
  238. 238. TODO, 2012‣ 內建聊天室、即時共筆‣ 匯出匯入、動態製圖‣ 與 Drupal 系統整合‣ 與 Socialtext 系統整合
  239. 239. TODO, 2012‣ 內建聊天室、即時共筆‣ 匯出匯入、動態製圖‣ 與 Drupal 系統整合‣ 與 Socialtext 系統整合‣ Forks welcome!
  240. 240. 感謝收看! EtherCalc 多人即時 協作試算表
  241. 241. EtherCalc以著作結合本文件之人,在法律許可之範圍內,拋棄該著作依著作權法所享有之權利,及其相關或鄰接的法律權利,宣告該著作貢獻至公共領域。採用 CC0 之著作,不要求姓名表彰。 ethercalc.tw

×