Slide 1

Slide 1 text

EtherCalc 多人即時 協作試算表

Slide 2

Slide 2 text

EtherCalc 多人即時 協作試算表 for Drupal

Slide 3

Slide 3 text

僅代表個人立場

Slide 4

Slide 4 text

只講故事 不講程式

Slide 5

Slide 5 text

只講故事 不講程式 概念

Slide 6

Slide 6 text

SheetNode.org

Slide 7

Slide 7 text

SheetNode.org

Slide 8

Slide 8 text

SheetNode.org ‣ npm install -g ethercalc ‣ ethercalc Please connect to: http://0:8000/

Slide 9

Slide 9 text

aosabook.org ⟪開源應用架構⟫ EtherCalc.tw

Slide 10

Slide 10 text

緣起

Slide 11

Slide 11 text

VisiCalc, 1979 Dan Bricklin

Slide 12

Slide 12 text

哈佛商學院, 1977

Slide 13

Slide 13 text

哈佛商學院, 1977

Slide 14

Slide 14 text

哈佛商學院, 1977

Slide 15

Slide 15 text

哈佛商學院, 1977

Slide 16

Slide 16 text

哈佛商學院, 1977

Slide 17

Slide 17 text

最初的願景

Slide 18

Slide 18 text

最初的願景 Alto 工作站

Slide 19

Slide 19 text

最初的願景 滑鼠計算機 Alto 工作站

Slide 20

Slide 20 text

最初的願景 頭戴顯示器 滑鼠計算機 Alto 工作站

Slide 21

Slide 21 text

最初的願景 頭戴顯示器 滑鼠計算機 Alto 工作站

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

=SUM( ) 0

Slide 25

Slide 25 text

10 20 30 =SUM( ) 0 10 30 60

Slide 26

Slide 26 text

10 20 30 =SUM( ) 0 10 30 60

Slide 27

Slide 27 text

1977 → 1978

Slide 28

Slide 28 text

1977 → 1978

Slide 29

Slide 29 text

1977 → 1978 Integer BASIC +

Slide 30

Slide 30 text

1978 → 1979

Slide 31

Slide 31 text

10 20 30 =SUM( ) 60 1978 → 1979

Slide 32

Slide 32 text

10 20 30 =SUM( ) 60 A B C D 1 2 1978 → 1979

Slide 33

Slide 33 text

10 20 30 =SUM( ) 60 A B C D 1 2 A1,B1,C1 1978 → 1979

Slide 34

Slide 34 text

Bob & Dan 10 20 30 =SUM( ) 60 A B C D 1 2 A1,B1,C1 1978 → 1979

Slide 35

Slide 35 text

Bob & Dan ‣6 年售出 700,000 套 10 20 30 =SUM( ) 60 A B C D 1 2 A1,B1,C1 1978 → 1979

Slide 36

Slide 36 text

Bob & Dan ‣6 年售出 700,000 套 ‣「殺手級應用」的始祖 10 20 30 =SUM( ) 60 A B C D 1 2 A1,B1,C1 1978 → 1979

Slide 37

Slide 37 text

1981

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

二十年來

Slide 44

Slide 44 text

二十年來

Slide 45

Slide 45 text

二十年來

Slide 46

Slide 46 text

二十年來

Slide 47

Slide 47 text

二十年來 始終如一

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

“打不開”

Slide 50

Slide 50 text

“打不開” “變亂碼”

Slide 51

Slide 51 text

“有病毒!” “打不開” “變亂碼”

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

維基百科, 2001

Slide 54

Slide 54 text

維基百科, 2001

Slide 55

Slide 55 text

維基百科, 2001

Slide 56

Slide 56 text

wikiCalc, 2005

Slide 57

Slide 57 text

✓ 跨伺服器引用數值。 wikiCalc, 2005

Slide 58

Slide 58 text

✓ 跨伺服器引用數值。 ✓ 保留每個版本,可隨時回復 。 wikiCalc, 2005

Slide 59

Slide 59 text

✓ 跨伺服器引用數值。 ✓ 保留每個版本,可隨時回復 。 ✓ 支援純文字、HTML、Wiki 語法。 wikiCalc, 2005

Slide 60

Slide 60 text

✓ 跨伺服器引用數值。 ✓ 保留每個版本,可隨時回復 。 ✓ 支援純文字、HTML、Wiki 語法。 ✓ 開放源碼! wikiCalc, 2005

Slide 61

Slide 61 text

wikiCalc.pl

Slide 62

Slide 62 text

網站 ./wkcdata/sites/Foo ./wkcdata/sites/Bar ./wkcdata/sites/Baz wikiCalc.pl

Slide 63

Slide 63 text

網站 ./wkcdata/sites/Foo ./wkcdata/sites/Bar ./wkcdata/sites/Baz wikiCalc.pl 頁面 XXX YYY ZZZ

Slide 64

Slide 64 text

網站 ./wkcdata/sites/Foo ./wkcdata/sites/Bar ./wkcdata/sites/Baz wikiCalc.pl 頁面 XXX YYY ZZZ 儲存格

Slide 65

Slide 65 text

網站 ./wkcdata/sites/Foo ./wkcdata/sites/Bar ./wkcdata/sites/Baz wikiCalc.pl 頁面 XXX YYY ZZZ 儲存格 A1: 100

Slide 66

Slide 66 text

網站 ./wkcdata/sites/Foo ./wkcdata/sites/Bar ./wkcdata/sites/Baz wikiCalc.pl 頁面 XXX YYY ZZZ 儲存格 A1: 100 A2: =A1*2

Slide 67

Slide 67 text

網站 ./wkcdata/sites/Foo ./wkcdata/sites/Bar ./wkcdata/sites/Baz wikiCalc.pl 頁面 XXX YYY ZZZ 儲存格 A1: 100 A2: =A1*2 B1: =XXX!C1

Slide 68

Slide 68 text

網站 ./wkcdata/sites/Foo ./wkcdata/sites/Bar ./wkcdata/sites/Baz wikiCalc.pl 頁面 XXX YYY ZZZ 儲存格 A1: 100 A2: =A1*2 B1: =XXX!C1

Slide 69

Slide 69 text

網站 ./wkcdata/sites/Foo ./wkcdata/sites/Bar ./wkcdata/sites/Baz wikiCalc.pl 頁面 XXX YYY ZZZ 儲存格 A1: 100 A2: =A1*2 B1: =XXX!C1 B2: =YYY!D2

Slide 70

Slide 70 text

網站 ./wkcdata/sites/Foo ./wkcdata/sites/Bar ./wkcdata/sites/Baz wikiCalc.pl 頁面 XXX YYY ZZZ 儲存格 A1: 100 A2: =A1*2 B1: =XXX!C1 B2: =YYY!D2

Slide 71

Slide 71 text

網站 ./wkcdata/sites/Foo ./wkcdata/sites/Bar ./wkcdata/sites/Baz wikiCalc.pl 頁面 XXX YYY ZZZ 儲存格 A1: 100 A2: =A1*2 B1: =XXX!C1 B2: =YYY!D2 跨頁引用

Slide 72

Slide 72 text

wikiCalc 編輯流程

Slide 73

Slide 73 text

wikiCalc 編輯流程 A1: 100 A2: =A1*2

Slide 74

Slide 74 text

wikiCalc 編輯流程 A1: 100 A2: =A1*2

Slide 75

Slide 75 text

wikicalc.pl wikiCalc 編輯流程 A1: 100 A2: =A1*2 POST / ajaxsetcell=host:page:A1:300

Slide 76

Slide 76 text

wikicalc.pl wikiCalc 編輯流程 A1: 100 A2: =A1*2 POST / ajaxsetcell=host:page:A1:300 200 OK

Slide 77

Slide 77 text

“載入中…”

Slide 78

Slide 78 text

“載入中…”

Slide 79

Slide 79 text

“載入中…” “C100k” 問題

Slide 80

Slide 80 text

“載入中…” “C100k” 問題

Slide 81

Slide 81 text

No content

Slide 82

Slide 82 text

打掉重練

Slide 83

Slide 83 text

打掉重練 ؄ڱ቎ࡣ

Slide 84

Slide 84 text

SocialCalc, 2006 Dan Bricklin Ross Mayfield

Slide 85

Slide 85 text

設計目標

Slide 86

Slide 86 text

設計目標 ‣引擎用 JavaScript 重寫。

Slide 87

Slide 87 text

設計目標 ‣引擎用 JavaScript 重寫。 ‣即時編輯及還原/重作。

Slide 88

Slide 88 text

設計目標 ‣引擎用 JavaScript 重寫。 ‣即時編輯及還原/重作。 ‣能處理十萬個儲存格。

Slide 89

Slide 89 text

系統架構

Slide 90

Slide 90 text

系統架構 SocialCalc.js HTTP Server

Slide 91

Slide 91 text

系統架構 SocialCalc.js HTTP Server GET

Slide 92

Slide 92 text

系統架構 SocialCalc.js HTTP Server GET

Slide 93

Slide 93 text

系統架構 SocialCalc.js HTTP Server GET GET

Slide 94

Slide 94 text

系統架構 SocialCalc.js HTTP Server GET GET ($)

Slide 95

Slide 95 text

系統架構 SocialCalc.js HTTP Server GET PUT GET ($)

Slide 96

Slide 96 text

指令設計模式

Slide 97

Slide 97 text

指令設計模式 set A1 value n 42

Slide 98

Slide 98 text

指令設計模式 set A1 value n 42 set A2 formula A1*2

Slide 99

Slide 99 text

指令設計模式 set A1 value n 42 set A2 formula A1*2 merge A1:B2 cut A3 paste A4 sort A1:B9 A up B down set sheet defaultcolor blue ...

Slide 100

Slide 100 text

指令設計模式 ‣ 背景處理計算。 set A1 value n 42 set A2 formula A1*2

Slide 101

Slide 101 text

指令設計模式 ‣ 背景處理計算。 ‣ 無限次還原重做。 set A1 value n 42 set A2 formula A1*2

Slide 102

Slide 102 text

指令設計模式 ‣ 背景處理計算。 ‣ 無限次還原重做。 ‣ 鍵盤滑鼠隨時可用! set A1 value n 42 set A2 formula A1*2

Slide 103

Slide 103 text

“社會化” 試算表

Slide 104

Slide 104 text

“社會化” 試算表

Slide 105

Slide 105 text

“社會化” 試算表 評論、按讚、推薦、 標記、分享、嵌入...

Slide 106

Slide 106 text

社會物件 㱻 人際連結

Slide 107

Slide 107 text

社會物件 㱻 人際連結

Slide 108

Slide 108 text

社會物件 㱻 人際連結

Slide 109

Slide 109 text

No content

Slide 110

Slide 110 text

工ӉϺЛх ࢰЗ્ЛЦ

Slide 111

Slide 111 text

CPAL 通用公共授權

Slide 112

Slide 112 text

CPAL 通用公共授權 ῜ BSD, MIT

Slide 113

Slide 113 text

CPAL 通用公共授權 ῜ BSD, MIT © LGPL, MPL

Slide 114

Slide 114 text

CPAL 通用公共授權 ῜ BSD, MIT © LGPL, MPL ++© GPL

Slide 115

Slide 115 text

CPAL 通用公共授權 ῜ BSD, MIT © LGPL, MPL ++© GPL “ASP

Slide 116

Slide 116 text

CPAL 通用公共授權 ῜ BSD, MIT © LGPL, MPL ++© GPL Affero GPL “ASP

Slide 117

Slide 117 text

CPAL 通用公共授權 ῜ BSD, MIT © LGPL, MPL ++© GPL Affero GPL CPAL “ASP

Slide 118

Slide 118 text

CPAL 通用公共授權 ῜ BSD, MIT © LGPL, MPL ++© GPL Affero GPL CPAL “ASP

Slide 119

Slide 119 text

CPAL 通用公共授權 ῜ BSD, MIT © LGPL, MPL ++© GPL Affero GPL CPAL “ASP

Slide 120

Slide 120 text

CPAL 通用公共授權 ῜ BSD, MIT © LGPL, MPL ++© GPL Affero GPL CPAL “ASP

Slide 121

Slide 121 text

Sheetnode, 2008 Karim Ratib

Slide 122

Slide 122 text

Sheetnode, 2008 Karim Ratib Views + Fields + CCK

Slide 123

Slide 123 text

Sheetnode, 2008 Karim Ratib Views + Fields + CCK SocialCalc.js

Slide 124

Slide 124 text

Sheetnode, 2008 Karim Ratib Views + Fields + CCK SocialCalc.js

Slide 125

Slide 125 text

Sheetnode, 2008 Karim Ratib Views + Fields + CCK SocialCalc.js

Slide 126

Slide 126 text

Sheetnode, 2008 Karim Ratib Views + Fields + CCK SocialCalc.js

Slide 127

Slide 127 text

Sheetnode, 2008

Slide 128

Slide 128 text

Sheetnode, 2008 I was looking for an open source equivalent to Google Docs that would allow tighter integration with a company's data:

Slide 129

Slide 129 text

Sheetnode, 2008 “Real-time reports, created out of Drupal data.” I was looking for an open source equivalent to Google Docs that would allow tighter integration with a company's data:

Slide 130

Slide 130 text

SheetNode.org

Slide 131

Slide 131 text

SheetNode.org

Slide 132

Slide 132 text

SheetNode.org Views

Slide 133

Slide 133 text

OLPC, 2008

Slide 134

Slide 134 text

Luke Closs & Dan OLPC, 2008

Slide 135

Slide 135 text

No content

Slide 136

Slide 136 text

No content

Slide 137

Slide 137 text

Mesh 網絡

Slide 138

Slide 138 text

No content

Slide 139

Slide 139 text

Manusheel Gupta Vijit Singh

Slide 140

Slide 140 text

Manusheel Gupta Vijit Singh SocialCalcActivity.py XoCom.py Gecko/XPCOM SocialCalc.js XoCom.js

Slide 141

Slide 141 text

Manusheel Gupta Vijit Singh SocialCalcActivity.py XoCom.py Gecko/XPCOM SocialCalc.js XoCom.js set A1 value n 42

Slide 142

Slide 142 text

Manusheel Gupta Vijit Singh SocialCalcActivity.py XoCom.py Gecko/XPCOM SocialCalc.js XoCom.js D-Bus + Telepathy set A1 value n 42

Slide 143

Slide 143 text

Manusheel Gupta Vijit Singh SocialCalcActivity.py XoCom.py Gecko/XPCOM SocialCalc.js XoCom.js D-Bus + Telepathy set A1 value n 42 OLPC Mesh 網絡廣播

Slide 144

Slide 144 text

Manusheel Gupta Vijit Singh SocialCalcActivity.py XoCom.py Gecko/XPCOM SocialCalc.js XoCom.js SocialCalcActivity.py XoCom.py Gecko/XPCOM SocialCalc.js XoCom.js D-Bus + Telepathy D-Bus + Telepathy set A1 value n 42 OLPC Mesh 網絡廣播

Slide 145

Slide 145 text

Manusheel Gupta Vijit Singh SocialCalcActivity.py XoCom.py Gecko/XPCOM SocialCalc.js XoCom.js SocialCalcActivity.py XoCom.py Gecko/XPCOM SocialCalc.js XoCom.js D-Bus + Telepathy D-Bus + Telepathy set A1 value n 42 set A1 value n 42 OLPC Mesh 網絡廣播

Slide 146

Slide 146 text

很讚,但是...

Slide 147

Slide 147 text

‣漏接訊息無法復原。 很讚,但是...

Slide 148

Slide 148 text

‣漏接訊息無法復原。 ‣編輯同一格時會衝突。 很讚,但是...

Slide 149

Slide 149 text

‣漏接訊息無法復原。 ‣編輯同一格時會衝突。 ‣只能在 OLPC 上使用! 很讚,但是...

Slide 150

Slide 150 text

YAPC::Tiny, 2009

Slide 151

Slide 151 text

EV: 事件驅動

Slide 152

Slide 152 text

Tatsumaki EV: 事件驅動 @miyagawa

Slide 153

Slide 153 text

Tatsumaki Web::Hippie @clkao EV: 事件驅動 @miyagawa

Slide 154

Slide 154 text

Tatsumaki Web::Hippie @clkao Feersum @stash EV: 事件驅動 @miyagawa

Slide 155

Slide 155 text

WebSocket 同步編輯 multiserver.pl Web::Hippie Plack Feersum EV/libev

Slide 156

Slide 156 text

WebSocket 同步編輯 multiserver.pl Web::Hippie Plack Feersum EV/libev ScheduleScheetCommand set A1 value n 2046 SpreadsheetControl RenderSheet

Slide 157

Slide 157 text

WebSocket 同步編輯 multiserver.pl Web::Hippie Plack Feersum EV/libev ScheduleScheetCommand set A1 value n 2046 SpreadsheetControl RenderSheet 傳送

Slide 158

Slide 158 text

WebSocket 同步編輯 multiserver.pl Web::Hippie Plack Feersum EV/libev ScheduleScheetCommand set A1 value n 2046 SpreadsheetControl RenderSheet 傳送 群播

Slide 159

Slide 159 text

WebSocket 同步編輯 multiserver.pl Web::Hippie Plack Feersum EV/libev ScheduleScheetCommand set A1 value n 2046 SpreadsheetControl RenderSheet 傳送 RenderSheet ScheduleScheetCommand (isRemote = true) set A1 value n 2046 群播

Slide 160

Slide 160 text

新增功能

Slide 161

Slide 161 text

✓斷線重連可以復原。 新增功能

Slide 162

Slide 162 text

✓斷線重連可以復原。 ✓顯示別人的游標位置。 新增功能

Slide 163

Slide 163 text

✓斷線重連可以復原。 ✓顯示別人的游標位置。 ✓可以在各平台上運行! 新增功能

Slide 164

Slide 164 text

✓斷線重連可以復原。 ✓顯示別人的游標位置。 ✓可以在各平台上運行! 新增功能

Slide 165

Slide 165 text

更讚了,但是...

Slide 166

Slide 166 text

‣要相信誰的目前狀態? 更讚了,但是...

Slide 167

Slide 167 text

‣要相信誰的目前狀態? ‣所有人離線:資料消失? 更讚了,但是...

Slide 168

Slide 168 text

‣要相信誰的目前狀態? ‣所有人離線:資料消失? ‣重新連接:回播所有指令? 更讚了,但是...

Slide 169

Slide 169 text

‣要相信誰的目前狀態? ‣所有人離線:資料消失? ‣重新連接:回播所有指令? 更讚了,但是...

Slide 170

Slide 170 text

No content

Slide 171

Slide 171 text

打掉重練

Slide 172

Slide 172 text

打掉重練 ؄ڱ቎ࡣ

Slide 173

Slide 173 text

YAPC::NA, 2006

Slide 174

Slide 174 text

“I think, but I cannot prove, that by the next year JavaScript 2.0 will bootstrap itself, complete self hosting, compile back to JavaScript, and replace Ruby as the Next Big Thing in all environments. ” YAPC::NA, 2006

Slide 175

Slide 175 text

YAPC::NA, 2006

Slide 176

Slide 176 text

YAPC::NA, 2006 “JavaScript will become the common backend for all dynamic languages, and so you can write Perl to run in the browser, on the server, and inside databases, all with the same set of development tools. ”

Slide 177

Slide 177 text

YAPC::NA, 2006

Slide 178

Slide 178 text

YAPC::NA, 2006 “Because, as we all know, worse is better, so the worst scripting language is doomed to become the best.”

Slide 179

Slide 179 text

YAPC::NA, 2006 “Because, as we all know, worse is better, so the worst scripting language is doomed to become the best.” 劣即是夯

Slide 180

Slide 180 text

No content

Slide 181

Slide 181 text

No content

Slide 182

Slide 182 text

No content

Slide 183

Slide 183 text

JavaScript: 缺點減少

Slide 184

Slide 184 text

JavaScript: 缺點減少 CoffeeScript: 標點減半 Jeremy Ashkenas cs = (js) -> js/2

Slide 185

Slide 185 text

JavaScript: 缺點減少 CoffeeScript: 標點減半 Jeremy Ashkenas cs = (js) -> js/2

Slide 186

Slide 186 text

JavaScript: 缺點減少 CoffeeScript: 標點減半 Jeremy Ashkenas cs = (js) -> js/2 “原 JavaScript 行數: 22k。  重寫過的 CoffeeScript 行數: 5k。  {async, jsdom, zappa, optimist etc}++”

Slide 187

Slide 187 text

No content

Slide 188

Slide 188 text

{x,y} = @offset

Slide 189

Slide 189 text

{x,y} = @offset var offset = this.offset;

Slide 190

Slide 190 text

{x,y} = @offset var offset = this.offset; var x = offset.x;

Slide 191

Slide 191 text

{x,y} = @offset var offset = this.offset; var x = offset.x; var y = offset.y;

Slide 192

Slide 192 text

{x,y} = @offset js2coffee.org var offset = this.offset; var x = offset.x; var y = offset.y;

Slide 193

Slide 193 text

COSCUP, 2011

Slide 194

Slide 194 text

COSCUP, 2011

Slide 195

Slide 195 text

COSCUP, 2011 hack

Slide 196

Slide 196 text

COSCUP, 2011 hack

Slide 197

Slide 197 text

EtherCalc 系統架構

Slide 198

Slide 198 text

EtherCalc 系統架構 main.coffee Zappa Socket.io Express Node.js EV/libuv sc.coffee SocialCalc.js db.coffee redis.js SocialCalc.js

Slide 199

Slide 199 text

EtherCalc 系統架構 main.coffee Zappa Socket.io Express Node.js EV/libuv sc.coffee SocialCalc.js db.coffee redis.js Redis (optional) SocialCalc.js

Slide 200

Slide 200 text

EtherCalc 系統架構 player.coffee SocialCalc.js main.coffee Zappa Socket.io Express Node.js EV/libuv sc.coffee SocialCalc.js db.coffee redis.js Redis (optional) SocialCalc.js SocialCalc.js

Slide 201

Slide 201 text

EtherCalc 系統架構 player.coffee SocialCalc.js main.coffee Zappa Socket.io Express Node.js EV/libuv sc.coffee SocialCalc.js db.coffee redis.js Redis (optional) GET snapshot LRANGE log SocialCalc.js SocialCalc.js

Slide 202

Slide 202 text

EtherCalc 系統架構 player.coffee SocialCalc.js main.coffee Zappa Socket.io Express Node.js EV/libuv sc.coffee SocialCalc.js db.coffee redis.js Redis (optional) RPUSH log cmd GET snapshot LRANGE log SocialCalc.js SocialCalc.js

Slide 203

Slide 203 text

EtherCalc 系統架構 player.coffee SocialCalc.js main.coffee Zappa Socket.io Express Node.js EV/libuv sc.coffee SocialCalc.js db.coffee redis.js Redis (optional) RPUSH log cmd GET snapshot LRANGE log SocialCalc.js SocialCalc.js

Slide 204

Slide 204 text

EtherCalc 系統架構 player.coffee SocialCalc.js main.coffee Zappa Socket.io Express Node.js EV/libuv sc.coffee SocialCalc.js db.coffee redis.js Redis (optional) RPUSH log cmd GET snapshot LRANGE log SocialCalc.js SocialCalc.js

Slide 205

Slide 205 text

EtherCalc 系統架構 player.coffee SocialCalc.js main.coffee Zappa Socket.io Express Node.js EV/libuv sc.coffee SocialCalc.js db.coffee redis.js Redis (optional) RPUSH log cmd GET snapshot LRANGE log DEL log SET snapshot snapshot SocialCalc.js SocialCalc.js

Slide 206

Slide 206 text

跨頁即時更新

Slide 207

Slide 207 text

跨頁即時更新 伺 服 端

Slide 208

Slide 208 text

跨頁即時更新 伺 服 端 客 戶 端

Slide 209

Slide 209 text

跨頁即時更新 ask.log: XXX 伺 服 端 客 戶 端

Slide 210

Slide 210 text

跨頁即時更新 ask.log: XXX log: XXX,snapshot,log 伺 服 端 客 戶 端

Slide 211

Slide 211 text

跨頁即時更新 ask.log: XXX log: XXX,snapshot,log execute: set A1 formula YYY!B2 伺 服 端 客 戶 端

Slide 212

Slide 212 text

跨頁即時更新 ask.log: XXX log: XXX,snapshot,log execute: set A1 formula YYY!B2 recalc: YYY,snapshot 伺 服 端 客 戶 端

Slide 213

Slide 213 text

跨頁即時更新 ask.log: XXX log: XXX,snapshot,log execute: set A1 formula YYY!B2 recalc: YYY,snapshot 伺 服 端 客 戶 端 recalc: YYY,snapshot

Slide 214

Slide 214 text

跨頁即時更新 ask.log: XXX log: XXX,snapshot,log execute: set A1 formula YYY!B2 recalc: YYY,snapshot 伺 服 端 客 戶 端 recalc: YYY,snapshot recalc: YYY,snapshot

Slide 215

Slide 215 text

REST 資源界面

Slide 216

Slide 216 text

REST 資源界面 GET /_/page PUT /_/page

Slide 217

Slide 217 text

REST 資源界面 GET /_/page PUT /_/page POST /_/page {commands:[…]}

Slide 218

Slide 218 text

REST 資源界面 GET /_/page PUT /_/page POST /_/page {commands:[…]} GET /_/page/cells/A1 PUT /_/page/cells/B2

Slide 219

Slide 219 text

No content

Slide 220

Slide 220 text

+ =

Slide 221

Slide 221 text

+ = Coco + =

Slide 222

Slide 222 text

+ = Coco + = + = Coco

Slide 223

Slide 223 text

No content

Slide 224

Slide 224 text

stove.on("heat", function() {

Slide 225

Slide 225 text

stove.on("heat", function() { pot.on("boil", function() {

Slide 226

Slide 226 text

stove.on("heat", function() { pot.on("boil", function() { rice.on("ready", function(dish) {

Slide 227

Slide 227 text

stove.on("heat", function() { pot.on("boil", function() { rice.on("ready", function(dish) { setTimeout(function() {

Slide 228

Slide 228 text

stove.on("heat", function() { pot.on("boil", function() { rice.on("ready", function(dish) { setTimeout(function() { dish.serve(); }, 60000);

Slide 229

Slide 229 text

stove.on("heat", function() { pot.on("boil", function() { rice.on("ready", function(dish) { setTimeout(function() { dish.serve(); }, 60000); }); }); });

Slide 230

Slide 230 text

stove.on("heat", function() { pot.on("boil", function() { rice.on("ready", function(dish) { setTimeout(function() { dish.serve(); }, 60000); }); }); });

Slide 231

Slide 231 text

stove.on("heat", function() { pot.on("boil", function() { rice.on("ready", function(dish) { setTimeout(function() { dish.serve(); }, 60000); }); }); });

Slide 232

Slide 232 text

No content

Slide 233

Slide 233 text

stove.on "heat", ->

Slide 234

Slide 234 text

stove.on "heat", -> pot.on "boil", ->

Slide 235

Slide 235 text

stove.on "heat", -> pot.on "boil", -> rice.on "ready", (dish) ->

Slide 236

Slide 236 text

stove.on "heat", -> pot.on "boil", -> rice.on "ready", (dish) -> setTimeout(

Slide 237

Slide 237 text

stove.on "heat", -> pot.on "boil", -> rice.on "ready", (dish) -> setTimeout( -> dish.serve()

Slide 238

Slide 238 text

stove.on "heat", -> pot.on "boil", -> rice.on "ready", (dish) -> setTimeout( -> dish.serve() 60000

Slide 239

Slide 239 text

stove.on "heat", -> pot.on "boil", -> rice.on "ready", (dish) -> setTimeout( -> dish.serve() 60000 )

Slide 240

Slide 240 text

stove.on "heat", -> pot.on "boil", -> rice.on "ready", (dish) -> setTimeout( -> dish.serve() 60000 )

Slide 241

Slide 241 text

No content

Slide 242

Slide 242 text

<- stove.on \heat

Slide 243

Slide 243 text

<- stove.on \heat <- pot.on \boil

Slide 244

Slide 244 text

<- stove.on \heat <- pot.on \boil dish <- rice.on \ready

Slide 245

Slide 245 text

<- stove.on \heat <- pot.on \boil dish <- rice.on \ready <- (`setTimeout` 60000)

Slide 246

Slide 246 text

<- stove.on \heat <- pot.on \boil dish <- rice.on \ready <- (`setTimeout` 60000) dish.serve!

Slide 247

Slide 247 text

<- stove.on \heat <- pot.on \boil dish <- rice.on \ready <- (`setTimeout` 60000) dish.serve!

Slide 248

Slide 248 text

OSDC.tw, 2012

Slide 249

Slide 249 text

OSDC.tw, 2012

Slide 250

Slide 250 text

OSDC.tw, 2012

Slide 251

Slide 251 text

OSDC.tw, 2012

Slide 252

Slide 252 text

哪來的「高風亮節」…

Slide 253

Slide 253 text

只是沒寫過 Drupal 模組。 哪來的「高風亮節」…

Slide 254

Slide 254 text

No content

Slide 255

Slide 255 text

雖然 Isis 架過 許多 Drupal 網站 我也幫忙改了一些…

Slide 256

Slide 256 text

雖然 Isis 架過 許多 Drupal 網站 我也幫忙改了一些…

Slide 257

Slide 257 text

雖然 Isis 架過 許多 Drupal 網站 我也幫忙改了一些…

Slide 258

Slide 258 text

雖然 Isis 架過 許多 Drupal 網站 我也幫忙改了一些…

Slide 259

Slide 259 text

可是我對架構 完全沒有概念。

Slide 260

Slide 260 text

可是我對架構 完全沒有概念。

Slide 261

Slide 261 text

No content

Slide 262

Slide 262 text

⟪開源之樂⟫, 2012. 7. 1.

Slide 263

Slide 263 text

⟪開源之樂⟫, 2012. 7. 1.

Slide 264

Slide 264 text

⟪開源之樂⟫, 2012. 7. 1.

Slide 265

Slide 265 text

⟪開源之樂⟫, 2012. 7. 1. “內容過於抽象。”

Slide 266

Slide 266 text

⟪開源之樂⟫, 2012. 7. 1. “內容過於抽象。” “這跟 Drupal 到底有何關係?”

Slide 267

Slide 267 text

No content

Slide 268

Slide 268 text

2012. 7. 2.

Slide 269

Slide 269 text

“你還是把 EtherCalc for Drupal 寫出來, 比較有意義。” 2012. 7. 2.

Slide 270

Slide 270 text

“你還是把 EtherCalc for Drupal 寫出來, 比較有意義。” 2012. 7. 2.

Slide 271

Slide 271 text

“你還是把 EtherCalc for Drupal 寫出來, 比較有意義。” 2012. 7. 2.

Slide 272

Slide 272 text

No content

Slide 273

Slide 273 text

2012. 7. 3.

Slide 274

Slide 274 text

2012. 7. 3. 感謝 Karim 幫忙

Slide 275

Slide 275 text

2012. 7. 3. 一個早上  就寫完了。 感謝 Karim 幫忙

Slide 276

Slide 276 text

/** * * Implements hook_menu(). * * In sheetnode_ethercalc_menu.info: * configure = admin/config/content/sheetnode/ethercalc * */ function sheetnode_ethercalc_menu() { array('admin/config/content/sheetnode/ethercalc' => array( 'title' => 'EtherCalc', 'access arguments' => array('administer site configuration'), 'page callback' => 'drupal_get_form', 'page arguments' => array('_sheetnode_ethercalc_settings'), 'description' => 'Administer settings for EtherCalc.', 'type' => MENU_LOCAL_TASK, )); }

Slide 277

Slide 277 text

/** * * Implements hook_menu(). * * In sheetnode_ethercalc_menu.info: * configure = admin/config/content/sheetnode/ethercalc * */ function sheetnode_ethercalc_menu() { array('admin/config/content/sheetnode/ethercalc' => array( 'title' => 'EtherCalc', 'access arguments' => array('administer site configuration'), 'page callback' => 'drupal_get_form', 'page arguments' => array('_sheetnode_ethercalc_settings'), 'description' => 'Administer settings for EtherCalc.', 'type' => MENU_LOCAL_TASK, )); }

Slide 278

Slide 278 text

/** * Implements hook_sheetnode_plugins(). */ function sheetnode_ethercalc_sheetnode_plugins( $value, $save_element, $context ) { // Only turn on Ethercalc if we're editing the node. if (!empty($save_element)) { $ethercalc_host = variable_get('sheetnode_ethercalc_host', ''); $ethercalc_port = variable_get('sheetnode_ethercalc_port', '8000'); $ethercalc_path = …; drupal_add_js($ethercalc_path . '/socket.io/socket.io.js#'); drupal_add_js($ethercalc_path . '/zappa/zappa.js#'); drupal_add_js($ethercalc_path . '/static/md5.js#'); drupal_add_js($ethercalc_path . '/player/broadcast.js#'); drupal_add_js($ethercalc_path . '/player/main.js#'); } }

Slide 279

Slide 279 text

/** * Implements hook_sheetnode_plugins(). */ function sheetnode_ethercalc_sheetnode_plugins( $value, $save_element, $context ) { // Only turn on Ethercalc if we're editing the node. if (!empty($save_element)) { $ethercalc_host = variable_get('sheetnode_ethercalc_host', ''); $ethercalc_port = variable_get('sheetnode_ethercalc_port', '8000'); $ethercalc_path = …; drupal_add_js($ethercalc_path . '/socket.io/socket.io.js#'); drupal_add_js($ethercalc_path . '/zappa/zappa.js#'); drupal_add_js($ethercalc_path . '/static/md5.js#'); drupal_add_js($ethercalc_path . '/player/broadcast.js#'); drupal_add_js($ethercalc_path . '/player/main.js#'); } }

Slide 280

Slide 280 text

No content

Slide 281

Slide 281 text

2012. 7. 4.

Slide 282

Slide 282 text

2012. 7. 4.

Slide 283

Slide 283 text

2012. 7. 4. Lith.tw

Slide 284

Slide 284 text

2012. 7. 4. Lith.tw

Slide 285

Slide 285 text

2012. 7. 4. Lith.tw

Slide 286

Slide 286 text

2012. 7. 4. Lith.tw

Slide 287

Slide 287 text

2012. 7. 4. Lith.tw

Slide 288

Slide 288 text

2012. 7. 4. Lith.tw

Slide 289

Slide 289 text

No content

Slide 290

Slide 290 text

結論是:

Slide 291

Slide 291 text

結論是:

Slide 292

Slide 292 text

寫 Drupal 模組 真的很簡單! 結論是:

Slide 293

Slide 293 text

感謝收看! EtherCalc for Drupal

Slide 294

Slide 294 text

以著作結合本文件之人,在法律許可 之範圍內,拋棄該著作依著作權法所 享有之權利,及其相關或鄰接的法律 權利,宣告該著作貢獻至公共領域。 採用 CC0 之著作,不要求姓名表彰。 EtherCalc SheetNode.org