@@ -41,13 +41,23 @@ class DataTransferItemStub implements DataTransferItem {
4141 }
4242}
4343
44+ function toAsciiLowercase ( value : string ) {
45+ return value . replace ( / [ A - Z ] / g, char => char . toLowerCase ( ) )
46+ }
47+
4448class DataTransferItemListStub
4549 extends Array < DataTransferItem >
4650 implements DataTransferItemList {
4751 add ( data : string , type : string ) : DataTransferItem
4852 add ( file : File ) : DataTransferItem
4953 add ( ...args : never [ ] ) {
50- const item = new DataTransferItemStub ( args [ 0 ] , args [ 1 ] )
54+ // The spec converts the type to ASCII lowercase here, but - unlike
55+ // `setData()` - does not replace the `text` and `url` shorthands.
56+ // https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransferitemlist-add
57+ const item =
58+ typeof args [ 0 ] === 'string'
59+ ? new DataTransferItemStub ( args [ 0 ] , toAsciiLowercase ( args [ 1 ] ) )
60+ : new DataTransferItemStub ( args [ 0 ] )
5161 this . push ( item )
5262 return item
5363 }
@@ -61,6 +71,18 @@ class DataTransferItemListStub
6171 }
6272}
6373
74+ // The spec requires the format to be converted to ASCII lowercase
75+ // and the shorthands `text` and `url` to be replaced with their MIME types.
76+ // https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-setdata
77+ function normalizeFormat ( format : string ) {
78+ const type = toAsciiLowercase ( format )
79+ return type === 'text'
80+ ? 'text/plain'
81+ : type === 'url'
82+ ? 'text/uri-list'
83+ : type
84+ }
85+
6486function getTypeMatcher ( type : string , exact : boolean ) {
6587 const [ group , sub ] = type . split ( '/' )
6688 const isGroup = ! sub || sub === '*'
@@ -76,9 +98,10 @@ function getTypeMatcher(type: string, exact: boolean) {
7698function createDataTransferStub ( window : Window & typeof globalThis ) {
7799 return new ( class DataTransferStub implements DataTransfer {
78100 getData ( format : string ) {
101+ const type = normalizeFormat ( format )
79102 const match =
80- this . items . find ( getTypeMatcher ( format , true ) ) ??
81- this . items . find ( getTypeMatcher ( format , false ) )
103+ this . items . find ( getTypeMatcher ( type , true ) ) ??
104+ this . items . find ( getTypeMatcher ( type , false ) )
82105
83106 let text = ''
84107 match ?. getAsString ( t => {
@@ -89,9 +112,10 @@ function createDataTransferStub(window: Window & typeof globalThis) {
89112 }
90113
91114 setData ( format : string , data : string ) {
92- const matchIndex = this . items . findIndex ( getTypeMatcher ( format , true ) )
115+ const type = normalizeFormat ( format )
116+ const matchIndex = this . items . findIndex ( getTypeMatcher ( type , true ) )
93117
94- const item = new DataTransferItemStub ( data , format ) as DataTransferItem
118+ const item = new DataTransferItemStub ( data , type ) as DataTransferItem
95119 if ( matchIndex >= 0 ) {
96120 this . items . splice ( matchIndex , 1 , item )
97121 } else {
@@ -101,7 +125,8 @@ function createDataTransferStub(window: Window & typeof globalThis) {
101125
102126 clearData ( format ?: string ) {
103127 if ( format ) {
104- const matchIndex = this . items . findIndex ( getTypeMatcher ( format , true ) )
128+ const type = normalizeFormat ( format )
129+ const matchIndex = this . items . findIndex ( getTypeMatcher ( type , true ) )
105130
106131 if ( matchIndex >= 0 ) {
107132 this . items . remove ( matchIndex )
0 commit comments