HTML 5 Native Drag
    楊維中(a.k.a zonble)
話說…
• 有次聽了一位資深 Web Developer   發表
 關於 HTML 5 的演講,裡頭提到 Native
 Drag
• …聽完覺得完全沒搔到癢處
• …果然要講跟 Native 有關的東西,你還
 是得要玩過一點 Native 的東西才行
在 Native Drag 之前?

• 網頁上的 Drag and Drop,其實就只是讓
 某個 HTML Element 移動位置而已

• 讓某個 HTML Element 跟著滑鼠
• 拉範圍不能超過目前網頁
Native Drag

• 將要透過 Drag and Drop 交換的資料寫入
 系統剪貼簿

 • Mac OS X:NSPasteboard
• 透過系統 API 設定滑鼠游標圖片
所以可以…

• 瀏覽器不同網頁之間 拉資料
• 不同瀏覽器之間 拉資料
• 瀏覽器與其他應用程式之間 拉資料
其實…
• 瀏覽器本來就有一定程度的 Native
 Drag,但是原本   限於部分種類的資
 料…

 • 文字
 • 圖片
以前的作法
• 如果想將 HTML 中出現一個可以    拉到
 瀏覽器之外的 custom 資料,我們需要寫
 一個瀏覽器 plug-in

• 瀏覽器 plug-in 就是在瀏覽器畫面中   出
 一塊 Native View,裡頭的實作當然就是
 Native 的,於是可以用 Native 方式交換
瀏覽器 Plug-in

• Windows:可能要寫 ActiveX Control,
 會有一堆安全性問題…

• Mac OS X:原本 WebKit Plug-in 超好寫,
 但是 10.7 Lion 之後禁止 Safari 載入
 WebKit Plug-in…
Demo

• Sample Code:https://github.com/zonble/
  NativeDrag
• 參考文件:WebKit DOM Programming
  Topics - Using Drag and Drop From
  JavaScript
WebView 與 NSTableView 交換資料
怎麼做

• 先解釋怎樣從 WebView   資料放到
 NSTableView
• 再解釋怎樣從 NSTableView   資料到
 WebView
從 WebView   資料放
  到 NSTableView
JavaScript
• 要讓一個 HTML Element 變成可以用
 Native Drag    拉

 • 加上 CSS 屬性:-webkit-user-drag:
   element;
 • 加上 ondragstart 的 handler
 • <div style=”-webkit-user-drag: element;”
JavaScript
呼叫系統剪貼簿
dragstart = function(this, event) {
     var dataTransfer = event.dataTransfer;
     dataTransfer.setData(“key”, “value
     string”);
     return true;
};
Objective C
•       冊可以 Drop 的 Data Type

    •   [self.tableView registerForDraggedTypes:@[@”key”]];

• NSView 需要實作 NSDraggingDestination
    才能支援 Drop 資料

• NSTableView DataSource 需要實作兩個
    method
Objective C
- (NSDragOperation)tableView:(NSTableView *)tableView
validateDrop:(id <NSDraggingInfo>)info proposedRow:
(NSInteger)row proposedDropOperation:
(NSTableViewDropOperation)dropOperation
{
	

 NSPasteboard *pasteBoard = [info draggingPasteboard];
	

 NSString *value = [pasteBoard stringForType:@”key”];
	

 if (value) {
	

 	

 return NSDragOperationCopy;
	

 }
	

 return NSDragOperationNone;
}
setData()
• JavaScript 會透過 dataTransfer 物件的
  setData() 與 getData() 交換資料

• …但是裡頭的資料目前只能夠是字串,
  如果是 array 等物件,會變成 [object
  Object]   類字串

• 所以如果是複雜的資料,我們可以一次
setData()
• 既然只能用字串…
 • 把 JavaScript 物件透過 JSON.stringify()
   與 JSON.parse() 轉成字串

 • Objective C 可以用 NSJSONSerialization
   或是其他第三方 JSON Parser
查看全部剪貼簿內容?




      Pasteboard Peeker
蘋果雖然說 Deprecated,但是還是很好用
從 NSTableView   資
 料放到 WebView
Objective C
• NSView 只要實作一個 method 就可以開
 始 Drag 東西出來

 • dragImage:at:offset:event:pasteboard:sour
   ce:slideBack:
• NSTableView DataSource 則是要實作
 tableView:writeRowsWithIndexes:toPasteb
Objective C
- (BOOL)tableView:(NSTableView *)tableView
writeRowsWithIndexes:(NSIndexSet *)rowIndexes
toPasteboard:(NSPasteboard *)pboard
{
	

 [pboard declareTypes:@[@”key”];
	

 [pboard setString:@"Value String"
forType:@”key”];
	

 return YES;
}
JavaScript
• 要讓一個 HTML Element 變成可以接受
  Drop
• 加上 CSS 屬性:-webkit-user-drop:
  element;
• 加上 ondragenter、ondragover、ondrop
  等 handler
JavaScript

• 文件上面說 ondragenter 與 ondragover 裡
  頭,一定要呼叫 event.preventDefault();
  不然沒有作用

• 我們可以從 dataTransfer.getData() 拿到
  NSTableView   過來的資料
Das ist alles.

Html 5 native drag

  • 1.
    HTML 5 NativeDrag 楊維中(a.k.a zonble)
  • 2.
    話說… • 有次聽了一位資深 WebDeveloper 發表 關於 HTML 5 的演講,裡頭提到 Native Drag • …聽完覺得完全沒搔到癢處 • …果然要講跟 Native 有關的東西,你還 是得要玩過一點 Native 的東西才行
  • 3.
    在 Native Drag之前? • 網頁上的 Drag and Drop,其實就只是讓 某個 HTML Element 移動位置而已 • 讓某個 HTML Element 跟著滑鼠 • 拉範圍不能超過目前網頁
  • 4.
    Native Drag • 將要透過Drag and Drop 交換的資料寫入 系統剪貼簿 • Mac OS X:NSPasteboard • 透過系統 API 設定滑鼠游標圖片
  • 5.
    所以可以… • 瀏覽器不同網頁之間 拉資料 •不同瀏覽器之間 拉資料 • 瀏覽器與其他應用程式之間 拉資料
  • 6.
    其實… • 瀏覽器本來就有一定程度的 Native Drag,但是原本 限於部分種類的資 料… • 文字 • 圖片
  • 7.
    以前的作法 • 如果想將 HTML中出現一個可以 拉到 瀏覽器之外的 custom 資料,我們需要寫 一個瀏覽器 plug-in • 瀏覽器 plug-in 就是在瀏覽器畫面中 出 一塊 Native View,裡頭的實作當然就是 Native 的,於是可以用 Native 方式交換
  • 8.
    瀏覽器 Plug-in • Windows:可能要寫ActiveX Control, 會有一堆安全性問題… • Mac OS X:原本 WebKit Plug-in 超好寫, 但是 10.7 Lion 之後禁止 Safari 載入 WebKit Plug-in…
  • 9.
    Demo • Sample Code:https://github.com/zonble/ NativeDrag • 參考文件:WebKit DOM Programming Topics - Using Drag and Drop From JavaScript
  • 10.
  • 11.
    怎麼做 • 先解釋怎樣從 WebView 資料放到 NSTableView • 再解釋怎樣從 NSTableView 資料到 WebView
  • 12.
    從 WebView 資料放 到 NSTableView
  • 13.
    JavaScript • 要讓一個 HTMLElement 變成可以用 Native Drag 拉 • 加上 CSS 屬性:-webkit-user-drag: element; • 加上 ondragstart 的 handler • <div style=”-webkit-user-drag: element;”
  • 14.
    JavaScript 呼叫系統剪貼簿 dragstart = function(this,event) { var dataTransfer = event.dataTransfer; dataTransfer.setData(“key”, “value string”); return true; };
  • 15.
    Objective C • 冊可以 Drop 的 Data Type • [self.tableView registerForDraggedTypes:@[@”key”]]; • NSView 需要實作 NSDraggingDestination 才能支援 Drop 資料 • NSTableView DataSource 需要實作兩個 method
  • 16.
    Objective C - (NSDragOperation)tableView:(NSTableView*)tableView validateDrop:(id <NSDraggingInfo>)info proposedRow: (NSInteger)row proposedDropOperation: (NSTableViewDropOperation)dropOperation { NSPasteboard *pasteBoard = [info draggingPasteboard]; NSString *value = [pasteBoard stringForType:@”key”]; if (value) { return NSDragOperationCopy; } return NSDragOperationNone; }
  • 17.
    setData() • JavaScript 會透過dataTransfer 物件的 setData() 與 getData() 交換資料 • …但是裡頭的資料目前只能夠是字串, 如果是 array 等物件,會變成 [object Object] 類字串 • 所以如果是複雜的資料,我們可以一次
  • 18.
    setData() • 既然只能用字串… •把 JavaScript 物件透過 JSON.stringify() 與 JSON.parse() 轉成字串 • Objective C 可以用 NSJSONSerialization 或是其他第三方 JSON Parser
  • 19.
    查看全部剪貼簿內容? Pasteboard Peeker 蘋果雖然說 Deprecated,但是還是很好用
  • 20.
    從 NSTableView 資 料放到 WebView
  • 21.
    Objective C • NSView只要實作一個 method 就可以開 始 Drag 東西出來 • dragImage:at:offset:event:pasteboard:sour ce:slideBack: • NSTableView DataSource 則是要實作 tableView:writeRowsWithIndexes:toPasteb
  • 22.
    Objective C - (BOOL)tableView:(NSTableView*)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard { [pboard declareTypes:@[@”key”]; [pboard setString:@"Value String" forType:@”key”]; return YES; }
  • 23.
    JavaScript • 要讓一個 HTMLElement 變成可以接受 Drop • 加上 CSS 屬性:-webkit-user-drop: element; • 加上 ondragenter、ondragover、ondrop 等 handler
  • 24.
    JavaScript • 文件上面說 ondragenter與 ondragover 裡 頭,一定要呼叫 event.preventDefault(); 不然沒有作用 • 我們可以從 dataTransfer.getData() 拿到 NSTableView 過來的資料
  • 25.