summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/editing/dnd/events
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/html/editing/dnd/events')
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/001-1.xhtml51
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/001.xhtml10
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/002-1.xhtml51
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/002.xhtml10
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/003-1.xhtml51
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/003.xhtml10
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/004.xhtml55
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/005.xhtml55
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/006.xhtml55
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/007.xhtml56
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/008.xhtml56
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/009.xhtml56
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/010.xhtml55
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/011.xhtml55
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/012.xhtml55
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/013.xhtml56
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/014.xhtml56
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/015.xhtml56
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/016.xhtml29
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/017.xhtml29
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/018.xhtml27
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/019.xhtml21
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/020.xhtml21
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/021.xhtml19
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/022.xhtml36
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/023.xhtml36
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/024.xhtml34
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/025.html69
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/026.html61
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/027.xhtml24
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/028.xhtml19
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/029.html79
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/030.html61
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/031-1.html25
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/031.html25
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/032.html81
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/033.html79
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/034.html56
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/035.html83
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/036.html70
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/037-proposed.xhtml86
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/037-spec.xhtml88
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/038-proposed.html84
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/drag-event-div-manual.html62
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/drag-event-manual.html62
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/dragend-event-manual.html64
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/dragenter-event-manual.html67
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/dragleave-event-manual.html66
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/dragover-event-manual.html64
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/dragstart-event-manual.html62
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/drop-event-manual.html64
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/events-cross-document-suite-HELPER-1.html205
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/events-cross-document-suite-HELPER-2.html77
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/events-cross-document-suite-manual.html12
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/events-file-suite-manual.html176
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/events-non-draggable-001-manual.html60
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/events-non-draggable-002-manual.html101
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/events-suite-manual.html371
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/helper-drag-me-input-with-circle.xhtml51
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/helper-drag-me-link-with-circle.xhtml51
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/helper-drag-me-p-with-circle.xhtml51
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/helper-drop-here-body-circle.xhtml51
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/historical-manual.html45
-rw-r--r--testing/web-platform/tests/html/editing/dnd/events/relatedTarget-attribute-manual.html65
64 files changed, 3918 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/editing/dnd/events/001-1.xhtml b/testing/web-platform/tests/html/editing/dnd/events/001-1.xhtml
new file mode 100644
index 0000000000..001d0b5c90
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/001-1.xhtml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Cross frame drag and drop: helper file</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function start(event)
+ {if(step++ == 1)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragstart should be first event to fire.')}
+ }
+function leavePage(event)
+ {if(step++ > 1)
+ {setColor('green green silver silver')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragleave should fire after dragstart.')}
+ }
+function endDrag(event)
+ {if(step++ > 2)
+ {setColor('green')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragend should fire after dragstart and dragleave.')}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body onload="window.getSelection().selectAllChildren(document.querySelector('p'))" ondragleave="leavePage(event)">
+<p ondragstart="start(event)" ondragend="endDrag(event)">Drag me</p>
+<p>Drag selected text to the frame below and drop it there. Both circles should turn green once text is dropped into lower frame.</p>
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/001.xhtml b/testing/web-platform/tests/html/editing/dnd/events/001.xhtml
new file mode 100644
index 0000000000..4c8e7d563e
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/001.xhtml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Drag and drop of selection between frames</title>
+</head>
+<frameset rows="50%, 50%">
+<frame src="001-1.xhtml"/>
+<frame src="helper-drop-here-body-circle.xhtml"/>
+</frameset>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/002-1.xhtml b/testing/web-platform/tests/html/editing/dnd/events/002-1.xhtml
new file mode 100644
index 0000000000..7e575b2eb6
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/002-1.xhtml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Cross frame drag and drop: helper file</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function start(event)
+ {if(step++ == 1)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragstart should be first event to fire.')}
+ }
+function leavePage(event)
+ {if(step++ > 1)
+ {setColor('green green silver silver')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragleave should fire after dragstart.')}
+ }
+function endDrag(event)
+ {if(step++ > 2)
+ {setColor('green')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragend should fire after dragstart and dragleave.')}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body onload="document.querySelector('input').select()" ondragleave="leavePage(event)">
+<p ondragstart="start(event)" ondragend="endDrag(event)"><input value="Drag me"/></p>
+<p>Drag selected text to the frame below and drop it there. Both circles should turn green once text is dropped into lower frame.</p>
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/002.xhtml b/testing/web-platform/tests/html/editing/dnd/events/002.xhtml
new file mode 100644
index 0000000000..9bd76db260
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/002.xhtml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Drag and drop of text input selection between frames</title>
+</head>
+<frameset rows="50%, 50%">
+<frame src="002-1.xhtml"/>
+<frame src="helper-drop-here-body-circle.xhtml"/>
+</frameset>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/003-1.xhtml b/testing/web-platform/tests/html/editing/dnd/events/003-1.xhtml
new file mode 100644
index 0000000000..2c7d3b9191
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/003-1.xhtml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Cross frame drag and drop: helper file</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function start(event)
+ {if(step++ == 1)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragstart should be first event to fire.')}
+ }
+function leavePage(event)
+ {if(step++ > 1)
+ {setColor('green green silver silver')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragleave should fire after dragstart.')}
+ }
+function endDrag(event)
+ {if(step++ > 2)
+ {setColor('green')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragend should fire after dragstart and dragleave.')}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body ondragleave="leavePage(event)">
+<p><a href="data:text/plain,1" ondragstart="start(event)" ondragend="endDrag(event)">Drag me</a></p>
+<p>Drag link to the frame below and drop it there. Both circles should turn green once link is dropped into lower frame.</p>
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/003.xhtml b/testing/web-platform/tests/html/editing/dnd/events/003.xhtml
new file mode 100644
index 0000000000..c853e931d5
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/003.xhtml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Drag and drop of link between frames</title>
+</head>
+<frameset rows="50%, 50%">
+<frame src="003-1.xhtml"/>
+<frame src="helper-drop-here-body-circle.xhtml"/>
+</frameset>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/004.xhtml b/testing/web-platform/tests/html/editing/dnd/events/004.xhtml
new file mode 100644
index 0000000000..85753621bb
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/004.xhtml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Drag and drop of selection to iframe</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+iframe
+ {width:100%;
+ height:500px;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function start(event)
+ {if(step++ == 1)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragstart should be first event to fire.')}
+ }
+function leavePage(event)
+ {if(step++ > 1)
+ {setColor('green green silver silver')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragleave should fire after dragstart.')}
+ }
+function endDrag(event)
+ {if(step++ > 2)
+ {setColor('green')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragend should fire after dragstart and dragleave.')}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body onload="window.getSelection().selectAllChildren(document.querySelector('p'))" ondragleave="leavePage(event)">
+<p ondragstart="start(event)" ondragend="endDrag(event)">Drag me</p>
+<p>Drag selected text to the frame below and drop it there. Both circles should turn green once text is dropped into lower frame.</p>
+<div/>
+<pre/>
+<iframe src="helper-drop-here-body-circle.xhtml">XHTML document</iframe>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/005.xhtml b/testing/web-platform/tests/html/editing/dnd/events/005.xhtml
new file mode 100644
index 0000000000..4ea0a9058d
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/005.xhtml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Drag and drop of text input selection to iframe</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+iframe
+ {width:100%;
+ height:500px;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function start(event)
+ {if(step++ == 1)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragstart should be first event to fire.')}
+ }
+function leavePage(event)
+ {if(step++ > 1)
+ {setColor('green green silver silver')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragleave should fire after dragstart.')}
+ }
+function endDrag(event)
+ {if(step++ > 2)
+ {setColor('green')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragend should fire after dragstart and dragleave.')}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body onload="document.querySelector('input').select()" ondragleave="leavePage(event)">
+<p ondragstart="start(event)" ondragend="endDrag(event)"><input value="Drag me"/></p>
+<p>Drag selected text to the frame below and drop it there. Both circles should turn green once text is dropped into lower frame.</p>
+<div/>
+<pre/>
+<iframe src="helper-drop-here-body-circle.xhtml">XHTML document</iframe>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/006.xhtml b/testing/web-platform/tests/html/editing/dnd/events/006.xhtml
new file mode 100644
index 0000000000..f9d659f31a
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/006.xhtml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Drag and drop of link to iframe</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+iframe
+ {width:100%;
+ height:500px;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function start(event)
+ {if(step++ == 1)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragstart should be first event to fire.')}
+ }
+function leavePage(event)
+ {if(step++ > 1)
+ {setColor('green green silver silver')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragleave should fire after dragstart.')}
+ }
+function endDrag(event)
+ {if(step++ > 2)
+ {setColor('green')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragend should fire after dragstart and dragleave.')}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body ondragleave="leavePage(event)">
+<p><a href="data:text/plain,1" ondragstart="start(event)" ondragend="endDrag(event)">Drag me</a></p>
+<p>Drag link to the frame below and drop it there. Both circles should turn green once link is dropped into lower frame.</p>
+<div/>
+<pre/>
+<iframe src="helper-drop-here-body-circle.xhtml">XHTML document</iframe>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/007.xhtml b/testing/web-platform/tests/html/editing/dnd/events/007.xhtml
new file mode 100644
index 0000000000..3c1c217a89
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/007.xhtml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Drag and drop of selection to object</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+object
+ {width:100%;
+ height:500px;
+ border:solid medium navy;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function start(event)
+ {if(step++ == 1)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragstart should be first event to fire.')}
+ }
+function leavePage(event)
+ {if(step++ > 1)
+ {setColor('green green silver silver')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragleave should fire after dragstart.')}
+ }
+function endDrag(event)
+ {if(step++ > 2)
+ {setColor('green')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragend should fire after dragstart and dragleave.')}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body onload="window.getSelection().selectAllChildren(document.querySelector('p'))" ondragleave="leavePage(event)">
+<p ondragstart="start(event)" ondragend="endDrag(event)">Drag me</p>
+<p>Drag selected text to the frame below and drop it there. Both circles should turn green once text is dropped into lower frame.</p>
+<div/>
+<pre/>
+<object type="application/xhtml+xml" data="helper-drop-here-body-circle.xhtml">XHTML document</object>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/008.xhtml b/testing/web-platform/tests/html/editing/dnd/events/008.xhtml
new file mode 100644
index 0000000000..e22695a692
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/008.xhtml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Drag and drop of text input selection to object</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+object
+ {width:100%;
+ height:500px;
+ border:solid medium navy;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function start(event)
+ {if(step++ == 1)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragstart should be first event to fire.')}
+ }
+function leavePage(event)
+ {if(step++ > 1)
+ {setColor('green green silver silver')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragleave should fire after dragstart.')}
+ }
+function endDrag(event)
+ {if(step++ > 2)
+ {setColor('green')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragend should fire after dragstart and dragleave.')}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body onload="document.querySelector('input').select()" ondragleave="leavePage(event)">
+<p ondragstart="start(event)" ondragend="endDrag(event)"><input value="Drag me"/></p>
+<p>Drag selected text to the frame below and drop it there. Both circles should turn green once text is dropped into lower frame.</p>
+<div/>
+<pre/>
+<object type="application/xhtml+xml" data="helper-drop-here-body-circle.xhtml">XHTML document</object>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/009.xhtml b/testing/web-platform/tests/html/editing/dnd/events/009.xhtml
new file mode 100644
index 0000000000..d2ddd32bdc
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/009.xhtml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Drag and drop of link to object</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+object
+ {width:100%;
+ height:500px;
+ border:solid medium navy;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function start(event)
+ {if(step++ == 1)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragstart should be first event to fire.')}
+ }
+function leavePage(event)
+ {if(step++ > 1)
+ {setColor('green green silver silver')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragleave should fire after dragstart.')}
+ }
+function endDrag(event)
+ {if(step++ > 2)
+ {setColor('green')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragend should fire after dragstart and dragleave.')}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body ondragleave="leavePage(event)">
+<p><a href="data:text/plain,1" ondragstart="start(event)" ondragend="endDrag(event)">Drag me</a></p>
+<p>Drag link to the frame below and drop it there. Both circles should turn green once link is dropped into lower frame.</p>
+<div/>
+<pre/>
+<object type="application/xhtml+xml" data="helper-drop-here-body-circle.xhtml">XHTML document</object>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/010.xhtml b/testing/web-platform/tests/html/editing/dnd/events/010.xhtml
new file mode 100644
index 0000000000..bbc2254282
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/010.xhtml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Drag and drop of selection from iframe</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+iframe
+ {width:100%;
+ height:300px;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function enterPage(event)
+ {event.preventDefault();
+ if(step++ > 0)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragenter should fire before dragover and drop');}
+ }
+function overPage(event)
+ {event.preventDefault();
+ if(step++ > 1)
+ {setColor('green green silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragover should fire after dragenter');}
+ }
+function dropIt(event)
+ {if(step++ > 1)
+ {setColor('green');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragover should fire after dragenter');}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body ondragenter="enterPage(event)" ondragover="overPage(event)" ondrop="dropIt(event)">
+<iframe src="helper-drag-me-p-with-circle.xhtml">XHTML document</iframe>
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/011.xhtml b/testing/web-platform/tests/html/editing/dnd/events/011.xhtml
new file mode 100644
index 0000000000..3ec4e5c40b
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/011.xhtml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Drag and drop of text input selection from iframe</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+iframe
+ {width:100%;
+ height:300px;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function enterPage(event)
+ {event.preventDefault();
+ if(step++ > 0)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragenter should fire before dragover and drop');}
+ }
+function overPage(event)
+ {event.preventDefault();
+ if(step++ > 1)
+ {setColor('green green silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragover should fire after dragenter');}
+ }
+function dropIt(event)
+ {if(step++ > 1)
+ {setColor('green');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragover should fire after dragenter');}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body ondragenter="enterPage(event)" ondragover="overPage(event)" ondrop="dropIt(event)">
+<iframe src="helper-drag-me-input-with-circle.xhtml">XHTML document</iframe>
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/012.xhtml b/testing/web-platform/tests/html/editing/dnd/events/012.xhtml
new file mode 100644
index 0000000000..0cebe5d895
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/012.xhtml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Drag and drop of link from iframe</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+iframe
+ {width:100%;
+ height:300px;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function enterPage(event)
+ {event.preventDefault();
+ if(step++ > 0)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragenter should fire before dragover and drop');}
+ }
+function overPage(event)
+ {event.preventDefault();
+ if(step++ > 1)
+ {setColor('green green silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragover should fire after dragenter');}
+ }
+function dropIt(event)
+ {if(step++ > 1)
+ {setColor('green');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragover should fire after dragenter');}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body ondragenter="enterPage(event)" ondragover="overPage(event)" ondrop="dropIt(event)">
+<iframe src="helper-drag-me-link-with-circle.xhtml">XHTML document</iframe>
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/013.xhtml b/testing/web-platform/tests/html/editing/dnd/events/013.xhtml
new file mode 100644
index 0000000000..3e6c19c402
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/013.xhtml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Drag and drop of selection from object</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+object
+ {width:100%;
+ height:300px;
+ border:solid medium navy;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function enterPage(event)
+ {event.preventDefault();
+ if(step++ > 0)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragenter should fire before dragover and drop');}
+ }
+function overPage(event)
+ {event.preventDefault();
+ if(step++ > 1)
+ {setColor('green green silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragover should fire after dragenter');}
+ }
+function dropIt(event)
+ {if(step++ > 1)
+ {setColor('green');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragover should fire after dragenter');}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body ondragenter="enterPage(event)" ondragover="overPage(event)" ondrop="dropIt(event)">
+<object type="application/xhtml+xml" data="helper-drag-me-p-with-circle.xhtml">XHTML document</object>
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/014.xhtml b/testing/web-platform/tests/html/editing/dnd/events/014.xhtml
new file mode 100644
index 0000000000..09abedd1f1
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/014.xhtml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Drag and drop of text input selection from object</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+object
+ {width:100%;
+ height:300px;
+ border:solid medium navy;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function enterPage(event)
+ {event.preventDefault();
+ if(step++ > 0)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragenter should fire before dragover and drop');}
+ }
+function overPage(event)
+ {event.preventDefault();
+ if(step++ > 1)
+ {setColor('green green silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragover should fire after dragenter');}
+ }
+function dropIt(event)
+ {if(step++ > 1)
+ {setColor('green');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragover should fire after dragenter');}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body ondragenter="enterPage(event)" ondragover="overPage(event)" ondrop="dropIt(event)">
+<object type="application/xhtml+xml" data="helper-drag-me-input-with-circle.xhtml">XHTML document</object>
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/015.xhtml b/testing/web-platform/tests/html/editing/dnd/events/015.xhtml
new file mode 100644
index 0000000000..7baf086b77
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/015.xhtml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Drag and drop of link from object</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+object
+ {width:100%;
+ height:300px;
+ border:solid medium navy;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function enterPage(event)
+ {event.preventDefault();
+ if(step++ > 0)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragenter should fire before dragover and drop');}
+ }
+function overPage(event)
+ {event.preventDefault();
+ if(step++ > 1)
+ {setColor('green green silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragover should fire after dragenter');}
+ }
+function dropIt(event)
+ {if(step++ > 1)
+ {setColor('green');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragover should fire after dragenter');}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body ondragenter="enterPage(event)" ondragover="overPage(event)" ondrop="dropIt(event)">
+<object type="application/xhtml+xml" data="helper-drag-me-link-with-circle.xhtml">XHTML document</object>
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/016.xhtml b/testing/web-platform/tests/html/editing/dnd/events/016.xhtml
new file mode 100644
index 0000000000..e6f9972a4d
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/016.xhtml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Selection drag and drop: events after dragenter is cancelled</title>
+<script type="application/ecmascript">
+function selectText()
+ {window.getSelection().selectAllChildren(document.querySelector('p'))}
+function start(event)
+ {event.preventDefault();}
+function dragMe(event)
+ {say('FAIL (drag event should not fire if dragstart is cancelled)');}
+function enterBody(event)
+ {event.preventDefault();
+ say('FAIL (dragover event should not fire if dragstart is cancelled)');}
+function overBody(event)
+ {event.preventDefault();
+ say('FAIL (dragover event should not fire if dragstart is cancelled)');}
+function dropIt(event)
+ {say('FAIL (drop event should not fire if dragstart is cancelled)');}
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'));}
+</script>
+</head>
+<body onload="selectText()" ondragenter="enterBody(event)" ondragover="overBody(event)" ondrop="dropIt(event)">
+<p ondragstart="start(event)" ondrag="dragMe(event)">Try to drag me</p>
+<p>You should not be able to drag text selection above.</p>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/017.xhtml b/testing/web-platform/tests/html/editing/dnd/events/017.xhtml
new file mode 100644
index 0000000000..0a372b5337
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/017.xhtml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Text input selection drag and drop: events after dragenter is cancelled</title>
+<script type="application/ecmascript">
+function selectText()
+ {document.querySelector('input').select()}
+function start(event)
+ {event.preventDefault();}
+function dragMe(event)
+ {say('FAIL (drag event should not fire if dragstart is cancelled)');}
+function enterBody(event)
+ {event.preventDefault();
+ say('FAIL (dragover event should not fire if dragstart is cancelled)');}
+function overBody(event)
+ {event.preventDefault();
+ say('FAIL (dragover event should not fire if dragstart is cancelled)');}
+function dropIt(event)
+ {say('FAIL (drop event should not fire if dragstart is cancelled)');}
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'));}
+</script>
+</head>
+<body onload="selectText()" ondragenter="enterBody(event)" ondragover="overBody(event)" ondrop="dropIt(event)">
+<p ondragstart="start(event)"><input value="Try to drag me" ondrag="dragMe(event)"/></p>
+<p>You should not be able to drag text selection above.</p>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/018.xhtml b/testing/web-platform/tests/html/editing/dnd/events/018.xhtml
new file mode 100644
index 0000000000..4aa8ba0997
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/018.xhtml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Link drag and drop: events after dragenter is cancelled</title>
+<script type="application/ecmascript">
+function start(event)
+ {event.preventDefault();}
+function dragMe(event)
+ {say('FAIL (drag event should not fire if dragstart is cancelled)');}
+function enterBody(event)
+ {event.preventDefault();
+ say('FAIL (dragover event should not fire if dragstart is cancelled)');}
+function overBody(event)
+ {event.preventDefault();
+ say('FAIL (dragover event should not fire if dragstart is cancelled)');}
+function dropIt(event)
+ {say('FAIL (drop event should not fire if dragstart is cancelled)');}
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'));}
+</script>
+</head>
+<body ondragenter="enterBody(event)" ondragover="overBody(event)" ondrop="dropIt(event)">
+<p><a href="data:text/plain,1" ondragstart="start(event)" ondrag="dragMe(event)">Try to drag me</a></p>
+<p>You should not be able to drag link above.</p>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/019.xhtml b/testing/web-platform/tests/html/editing/dnd/events/019.xhtml
new file mode 100644
index 0000000000..4e718dda27
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/019.xhtml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Selection drag and drop: events after drag is cancelled</title>
+<script type="application/ecmascript">
+function selectText()
+ {window.getSelection().selectAllChildren(document.querySelector('p'))}
+function dragMe(event)
+ {event.preventDefault();}
+function dropIt(event)
+ {say('FAIL (no drop should occur after drag is cancelled)')}
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'));}
+</script>
+</head>
+<body onload="selectText()" dropzone="copy string:text/plain" ondrop="dropIt(event)">
+<p ondrag="dragMe(event)">Try to drag me</p>
+<p>You should not be able to drop text selection above.</p>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/020.xhtml b/testing/web-platform/tests/html/editing/dnd/events/020.xhtml
new file mode 100644
index 0000000000..4a1d60a647
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/020.xhtml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Text input selection drag and drop: events after drag is cancelled</title>
+<script type="application/ecmascript">
+function selectText()
+ {document.querySelector('input').select()}
+function dragMe(event)
+ {event.preventDefault();}
+function dropIt(event)
+ {say('FAIL (no drop should occur after drag is cancelled)')}
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'));}
+</script>
+</head>
+<body onload="selectText()" dropzone="copy string:text/plain" ondrop="dropIt(event)">
+<p><input value="Try to drag me" ondrag="dragMe(event)"/></p>
+<p>You should not be able to drop text selection above.</p>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/021.xhtml b/testing/web-platform/tests/html/editing/dnd/events/021.xhtml
new file mode 100644
index 0000000000..6cca911f1d
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/021.xhtml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Link drag and drop: events after drag is cancelled</title>
+<script type="application/ecmascript">
+function dragMe(event)
+ {event.preventDefault();}
+function dropIt(event)
+ {say('FAIL (no drop should occur after drag is cancelled)')}
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'));}
+</script>
+</head>
+<body dropzone="copy string:text/uri-list" ondrop="dropIt(event)">
+<p><a href="data:text/plain,1" ondrag="dragMe(event)">Try to drag me</a></p>
+<p>You should not be able to drag link above.</p>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/022.xhtml b/testing/web-platform/tests/html/editing/dnd/events/022.xhtml
new file mode 100644
index 0000000000..98773f2cb6
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/022.xhtml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Selection drag and drop: events after drag and drop is cancelled</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;}
+</style>
+<script type="application/ecmascript">
+var result = true;
+function selectText()
+ {window.getSelection().selectAllChildren(document.querySelector('p'))}
+function dropIt(event)
+ {result = false;
+ setColor('maroon');
+ say('drop event : FAIL (no drop should occur once drag and drop is cancelled)')}
+function endDrag(event)
+ {if(result)
+ {setColor('teal')}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'));}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body onload="selectText()" dropzone="copy string:text/plain" ondrop="dropIt(event)">
+<p ondragstart="setColor('teal silver silver silver')" ondragend="endDrag(event)">Drag me</p>
+<p>Drag selected text and press Esc before you drop it. Circle below should turn green once drag and drop is cancelled.</p>
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/023.xhtml b/testing/web-platform/tests/html/editing/dnd/events/023.xhtml
new file mode 100644
index 0000000000..fadf76bf27
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/023.xhtml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Text input selection drag and drop: events after drag and drop is cancelled</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;}
+</style>
+<script type="application/ecmascript">
+var result = true;
+function selectText()
+ {document.querySelector('input').select()}
+function dropIt(event)
+ {result = false;
+ setColor('maroon');
+ say('drop event : FAIL (no drop should occur once drag and drop is cancelled)')}
+function endDrag(event)
+ {if(result)
+ {setColor('teal')}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'));}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body onload="selectText()" dropzone="copy string:text/plain" ondrop="dropIt(event)">
+<p><input value="Drag me" ondragstart="setColor('teal silver silver silver')" ondragend="endDrag(event)"/></p>
+<p>Drag selected text and press Esc before you drop it. Circle below should turn green once drag and drop is cancelled.</p>
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/024.xhtml b/testing/web-platform/tests/html/editing/dnd/events/024.xhtml
new file mode 100644
index 0000000000..9afa8f709a
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/024.xhtml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Link drag and drop: events after drag and drop is cancelled</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;}
+</style>
+<script type="application/ecmascript">
+var result = true;
+function dropIt(event)
+ {result = false;
+ setColor('maroon');
+ say('drop event : FAIL (no drop should occur once drag and drop is cancelled)')}
+function endDrag(event)
+ {if(result)
+ {setColor('teal')}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'));}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body dropzone="copy string:text/uri-list" ondrop="dropIt(event)">
+<p><a href="data:text/plain,1" ondragstart="setColor('teal silver silver silver')" ondragend="endDrag(event)">Drag me</a></p>
+<p>Drag link and press Esc before you drop it. Circle below should turn green once drag and drop is cancelled.</p>
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/025.html b/testing/web-platform/tests/html/editing/dnd/events/025.html
new file mode 100644
index 0000000000..b4bbbc547e
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/025.html
@@ -0,0 +1,69 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Dragover repeating</title>
+ <style type="text/css">
+div:first-child {
+ height: 100px;
+ width: 100px;
+ background: orange;
+ display: inline-block;
+}
+div:first-child + div {
+ height: 100px;
+ width: 100px;
+ background: blue;
+ display: inline-block;
+}
+ </style>
+ <script type="text/javascript">
+window.onload = function () {
+ var numsecs = 5, maxpolltime = 0.550, minpolltime = 0.150;
+ var blue = document.getElementsByTagName('div')[1], p = document.getElementsByTagName('p')[0];
+ var numfired = 0, readytocount = false;
+ document.getElementsByTagName('div')[0].ondragstart = function (e) {
+ e.dataTransfer.effectAllowed = 'all';
+ e.dataTransfer.setData('text','dummy text');
+ };
+ blue.ondrop = function (e) {
+ e.preventDefault();
+ };
+ blue.ondragover = function (e) {
+ e.preventDefault();
+ if( readytocount ) { numfired++; }
+ };
+ blue.ondragenter = function (e) {
+ e.preventDefault();
+ p.innerHTML = 'Keep the mouse perfectly still...';
+ //give the tester a second to get ready
+ setTimeout(function () {
+ readytocount = true;
+ numfired = 0;
+ p.innerHTML = 'Keep the mouse perfectly still for '+numsecs+' seconds';
+ var countsecs = numsecs;
+ var intr = setInterval(function () {
+ countsecs--;
+ if( countsecs ) {
+ p.innerHTML = 'Keep the mouse perfectly still for '+countsecs+' seconds';
+ } else {
+ clearInterval(intr);
+ var passed = numfired >= Math.floor( numsecs / maxpolltime ) && numfired <= Math.floor( numsecs / minpolltime );
+ document.getElementsByTagName('p')[0].innerHTML = ( passed ? 'PASS' : 'FAIL' ) +
+ '<br><br>(Fired ' + numfired + ' times in ' + numsecs + ' seconds, must be between ' +
+ Math.floor( numsecs / maxpolltime ) + ' and ' + Math.floor( numsecs / minpolltime ) + ')<br>You can release the drag now';
+ }
+ },1000);
+ },1000);
+ };
+};
+ </script>
+ </head>
+ <body>
+
+ <div draggable="true"></div>
+ <div></div>
+ <p>Drag the orange square over the blue square, then keep the mouse perfectly still until the result appears.</p>
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/026.html b/testing/web-platform/tests/html/editing/dnd/events/026.html
new file mode 100644
index 0000000000..816155a09d
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/026.html
@@ -0,0 +1,61 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Drag repeating</title>
+ <style type="text/css">
+div:first-child {
+ height: 100px;
+ width: 100px;
+ background: orange;
+ display: inline-block;
+}
+div:first-child + div {
+ height: 100px;
+ width: 100px;
+ background: blue;
+ display: inline-block;
+}
+ </style>
+ <script type="text/javascript">
+window.onload = function () {
+ var numsecs = 5, maxpolltime = 0.550, minpolltime = 0.150;
+ var orange = document.getElementsByTagName('div')[0], p = document.getElementsByTagName('p')[0];
+ var numfired = 0, readytocount = false;
+ document.getElementsByTagName('div')[0].ondragstart = function (e) {
+ e.dataTransfer.effectAllowed = 'all';
+ e.dataTransfer.setData('text','dummy text');
+ p.innerHTML = 'Keep the mouse perfectly still...';
+ //give the tester a second to get ready
+ setTimeout(function () {
+ readytocount = true;
+ numfired = 0;
+ p.innerHTML = 'Keep the mouse perfectly still for '+numsecs+' seconds';
+ var countsecs = numsecs;
+ var intr = setInterval(function () {
+ countsecs--;
+ if( countsecs ) {
+ p.innerHTML = 'Keep the mouse perfectly still for '+countsecs+' seconds';
+ } else {
+ clearInterval(intr);
+ var passed = numfired >= Math.floor( numsecs / maxpolltime ) && numfired <= Math.floor( numsecs / minpolltime );
+ document.getElementsByTagName('p')[0].innerHTML = ( passed ? 'PASS' : 'FAIL' ) +
+ '<br><br>(Fired ' + numfired + ' times in ' + numsecs + ' seconds, must be between ' +
+ Math.floor( numsecs / maxpolltime ) + ' and ' + Math.floor( numsecs / minpolltime ) + ')<br>You can release the drag now';
+ }
+ },1000);
+ },1000);
+ };
+ orange.ondrag = function (e) {
+ if( readytocount ) { numfired++; }
+ };
+};
+ </script>
+ </head>
+ <body>
+
+ <div draggable="true"></div>
+ <p>Drag the orange square sideways until the drag placeholder appears, then keep the mouse perfectly still until the result appears.</p>
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/027.xhtml b/testing/web-platform/tests/html/editing/dnd/events/027.xhtml
new file mode 100644
index 0000000000..983bcd298b
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/027.xhtml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>PNG image drag and drop: 'return false' should not cancel event</title>
+<style type="text/css">
+div
+ {height:100px;
+ width:100px;
+ padding:20px;
+ background-color:silver;}
+</style>
+<script type="application/ecmascript">
+function addImage(event)
+ {var c = document.createElement('img');
+ c.setAttribute('src',event.dataTransfer.getData('text/uri-list').replace(/\r\n$/,''));
+ document.querySelector('div').appendChild(c);}
+</script>
+</head>
+<body onload="document.querySelector('img').addEventListener('drag',function (){return false},false)">
+<p><img ondragstart="event.dataTransfer.effectAllowed = 'copy'" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAEq0lEQVR42u1dvU4bQRAeR0RCCilSp0peIoKGB4DSXYRDlcZlFClKBI4bB/kV/AymIDwCTahiicaioEOxhCsjWVTJziyKMfYZn+9ud3bvG2mEZB13u9+nndmf2Rki7fKFXtEBbVKD9o22jB4bPaND6hm9Mjo0enevw/vfevKMfbYl/8vv4HdBUkvFALhltG2A7dN3+pur8jv53fwN/hZkjjRo3eiuAatjdJA7CcnkDOSb/G1uQ6mFzUeDagaQrvl764yEJOU22LbUymXaGrRhOt40OvJOQvLIGUkbP9GLeIn4SM9NJ+tOTVI+Jq0ubY9sVFRNxy6DIWKWmEvpQ/ByQNumI+fBEjHrZ86lT8HJV3ptGn8aDRGzxJxKHwMZFe9Mg6+jJWNCyrX0VbUc0nuj4+jJmPiWsfRZodN+ZvSoNETMjpYjwUCFfKaXpjEnpSVjQsqJYOF5ZLw1elF6MiakXAgmnpw378DegIgZUm4EGw8jA2QsIuUbvXHpM2CmljFfhfsUO5uCA0/j6AudfZV5arv6WuVHcYs+ALwqKTkvHnmLoEwr8CJW9Llts9iNwvj3plzsfeWyIRnzrq37kfIzq6naBpA5a6bzlJgOl/SMkl+rklEFgIX5k5THwTYgIdwzcP2jhM/o19KsOeoArnBS6suaqo2gQnXCJWSwXNwXB4gBMFekNBeTwSGUmiMK4yNktDhsleNaAZRrUvYWmasuQHJOSDdpdKyriEIvo9maexWC70gAIF/bKTvzzFUH4HgbJZ3HdFSw9vC6lfKHpq7X8X07AOOblK2HhLQBindC2g/9Rx+gePcj/cnqHIDoUFm1c9gjwNAy/d0kyXIAMLSYrQ8kqScAhhbH3iLJBwIwtBByTJKkBWBoIeSMJHMOwNBCyG+SdEYAQ4tTvyLJMQUwtBAyJEn8BTC0EHIHQhQSApOlzGTBqaty6jzVAhhaCOlhYahuYYitE02EHGNzURchLZItX4ChhZB9HFBpUjmgwhGuHv0feI0gBw1T3j7CgHT5jzYC5XQRsjUdSsrhjADGl7ka0EylBgRb+ySkMy9rww7A8Waududf2MH9Qh9k3CbXLsGVNh/mqrvojuEeQHI+Qmq4Fq1ndIyeruaDxAEuCWk+ncmB0z3gepubtQenMUHyGTWELJl8xk6B15CeqVAyLtPXtUICsyJnVivWs+J0dAAwbzLOkQRTk2YuKsapTQFkXqPjlDILEinnRcZ1fpXdkGo866xqnH9FNyTjz0JIQZXcuPQCAE5rqo6oMEFBl7RknBRfTg8lj5Yl48JdGT0ueIWiYIvIuHFfPg9l85LJcF42b+JTUFjysZnyVlhy2qfA0asovTo9+0JxYnWC8t0KBQXuFYrdkIy3mBj3LbeNQrejZTuqOlbcl8znGTqcfjXoM3pboqgaPhEPxda1qgcVYsRt5TanDkgISWzcV1N1hCS3jdu4dNxUDMIhlBzXysHGGspkcBtsW2pPh3fGLrZ2ya5cXHFp0qxJ6si3E68EQCpy344vQRZxO5jfye+2d/oqgHsV02Z3lvcl9QTnA+EkLZw5h9MZcY4pTvxldXj/W0+esc+25H/5HQGYon+Q5f+MwFz+8QAAAABJRU5ErkJggg==" alt="PNG circle"/></p>
+<p>Drag green circle to the silver box below and drop it. It should be copied to the box once you drop it there.</p>
+<div ondragenter="event.preventDefault()" ondragover="return false" ondrop="addImage(event)"/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/028.xhtml b/testing/web-platform/tests/html/editing/dnd/events/028.xhtml
new file mode 100644
index 0000000000..35c69766f6
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/028.xhtml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Link drag and drop: 'return false' should not cancel event</title>
+<style type="text/css">
+div
+ {min-height:100px;
+ width:100px;
+ padding:20px;
+ color:white;
+ background-color:navy;}
+</style>
+</head>
+<body onload="document.querySelector('a').addEventListener('drag',function (){return false},false)">
+<p><a href="data:text/plain,1" ondragstart="event.dataTransfer.effectAllowed = 'copy'">Drag me</a></p>
+<p>Drag link above to the navy box below and drop it. You should see word PASS once you drop it in the box.</p>
+<div ondragenter="event.preventDefault()" ondragover="return false" ondrop="document.querySelector('div').appendChild(document.createTextNode((event.dataTransfer.getData('text/uri-list').replace(/\r\n$/,'') == 'data:text/plain,1')?'PASS':'FAIL'))"/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/029.html b/testing/web-platform/tests/html/editing/dnd/events/029.html
new file mode 100644
index 0000000000..70c243d993
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/029.html
@@ -0,0 +1,79 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Drag and drop without cancelling dragenter</title>
+ <style type="text/css">
+div:first-child {
+ height: 100px;
+ width: 100px;
+ background: orange;
+ display: inline-block;
+}
+div:first-child + div {
+ height: 100px;
+ width: 100px;
+ background: blue;
+ display: inline-block;
+}
+ </style>
+ <script type="text/javascript">
+
+window.onload = function () {
+ var drag = document.getElementsByTagName('div')[0], sequence = [];
+ drag.ondragstart = function (e) {
+ e.dataTransfer.setData('text','hello');
+ e.dataTransfer.effectAllowed = 'copy';
+ };
+ drag.ondragenter = drag.ondragover = function (e) {
+ e.preventDefault();
+ };
+ var drop = document.getElementsByTagName('div')[1], dragoverhasfired = false;
+ drop.ondragenter = function (e) {
+ dragoverhasfired = true; //events targeting body will be ignored until this event has fired
+ sequence[sequence.length] = 'drop.dragenter';
+ };
+ drop.ondragover = function (e) {
+ e.preventDefault();
+ if( sequence[sequence.length-1] != 'drop.dragover' ) {
+ sequence[sequence.length] = 'drop.dragover';
+ }
+ };
+ drop.ondrop = function (e) {
+ e.preventDefault();
+ sequence[sequence.length] = 'drop.ondrop';
+ };
+ document.body.ondragenter = function (e) {
+ if( e.target != this ) { return; }
+ if( dragoverhasfired ) {
+ sequence[sequence.length] = 'body.dragenter';
+ }
+ };
+ document.body.ondragover = function (e) {
+ if( e.target != this ) { return; }
+ if( dragoverhasfired ) {
+ if( sequence[sequence.length-1] != 'body.dragover' ) {
+ sequence[sequence.length] = 'body.dragover';
+ }
+ }
+ };
+ drag.ondragend = function (e) {
+ sequence = sequence.join('=&gt;')
+ var desiredsequence = (['drop.dragenter','body.dragenter','body.dragover']).join('=&gt;')
+ if( sequence == desiredsequence ) {
+ document.getElementsByTagName('div')[2].innerHTML = 'PASS';
+ } else {
+ document.getElementsByTagName('div')[2].innerHTML = 'FAIL, got:<br>'+sequence+'<br>instead of:<br>'+desiredsequence;
+ }
+ };
+};
+ </script>
+ </head>
+ <body>
+
+ <div draggable="true"></div><div></div>
+ <div>&nbsp;</div>
+ <p>Drag the orange square onto the blue square and release it.</p>
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/030.html b/testing/web-platform/tests/html/editing/dnd/events/030.html
new file mode 100644
index 0000000000..8dc573474d
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/030.html
@@ -0,0 +1,61 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Drag and drop without cancelling dragenter on body</title>
+ <style type="text/css">
+div:first-child {
+ height: 100px;
+ width: 100px;
+ background: orange;
+ display: inline-block;
+}
+div:first-child + div {
+ height: 100px;
+ width: 100px;
+ margin-left: 100px;
+ background: blue;
+ display: inline-block;
+}
+ </style>
+ <script type="text/javascript">
+//If dragenter is cancelled the body should then become the target element, receiving both a dragenter and a dragover event.
+//When the body is the actual immediate user selection (first time over the body), that means it gets *2* dragenter events
+//Then when a div becomes immediate user selection (blue) but does not cancel the dragenter event, dragenter does not need
+//to fire on body because body is already the current target element
+//Then when the body is the actual immediate user selection again (second time over the body), it is already the current
+//target element, so does not get a dragenter event
+window.onload = function () {
+ var drag = document.getElementsByTagName('div')[0], beforecount = 0, aftercount = 0, switchcount = false;
+ drag.ondragstart = function (e) {
+ e.dataTransfer.setData('text','hello');
+ e.dataTransfer.effectAllowed = 'copy';
+ };
+ drag.ondragenter = drag.ondrop = drag.ondragover = function (e) {
+ e.preventDefault();
+ };
+ var drop = document.getElementsByTagName('div')[1];
+ drop.ondragenter = function (e) {
+ switchcount = true;
+ };
+ drop.ondragover = function (e) {
+ e.preventDefault();
+ };
+ document.body.ondragenter = function (e) {
+ if( e.target != this ) { return; }
+ if( switchcount ) { aftercount++; } else { beforecount++; }
+ };
+ drag.ondragend = function (e) {
+ document.getElementsByTagName('div')[2].innerHTML = ( beforecount == 2 && aftercount == 0 ) ? 'PASS' : ( 'FAIL, dragenter fired on body '+beforecount+' time(s) before blue.ondragenter and '+aftercount+' time(s) afterwards, instead of 2 and 0 times respectively' );
+ };
+};
+ </script>
+ </head>
+ <body>
+
+ <div draggable="true"></div><div></div>
+ <div>&nbsp;</div>
+ <p>Drag the orange square onto the blue square, then back to the orange square, and release it.</p>
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/031-1.html b/testing/web-platform/tests/html/editing/dnd/events/031-1.html
new file mode 100644
index 0000000000..b70082ba21
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/031-1.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Non-rendered body should still become current target element</title>
+ <style type="text/css">
+html { background: blue; }
+ </style>
+ </head>
+ <body>
+
+ <script type="text/javascript">
+var seentypes = {};
+document.body.ondragenter = document.body.ondragover = document.body.ondrop = function (e) {
+ e.preventDefault();
+ //document.body.innerHTML += e.type;
+ if( e.type == 'drop' ) {
+ document.body.innerHTML = ( seentypes.dragenter && seentypes.dragover ) ? 'PASS' : 'FAIL';
+ } else {
+ seentypes[e.type] = true;
+ }
+}
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/031.html b/testing/web-platform/tests/html/editing/dnd/events/031.html
new file mode 100644
index 0000000000..92220e30e1
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/031.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Non-rendered body should still become current target element</title>
+ <style type="text/css">
+span { background: orange; display: inline-block; height: 200px; width: 200px; }
+iframe { border: none; }
+ </style>
+ <script type="text/javascript">
+window.onload = function () {
+ document.getElementsByTagName('span')[0].ondragstart = function (e) {
+ e.dataTransfer.setData('text','dummy text');
+ e.dataTransfer.effectAllowed = 'copy';
+ };
+};
+ </script>
+ </head>
+ <body>
+
+ <p>Drag the orange square onto the blue square and release it. Fail if text does not appear in the blue square.</p>
+ <p><span draggable="true"></span> <iframe height="200" width="200" src="031-1.html"></iframe></p>
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/032.html b/testing/web-platform/tests/html/editing/dnd/events/032.html
new file mode 100644
index 0000000000..a928a3c425
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/032.html
@@ -0,0 +1,81 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Drag and drop passing over body without cancelling dragenter</title>
+ <style type="text/css">
+div:first-child {
+ height: 100px;
+ width: 100px;
+ background: orange;
+ display: inline-block;
+}
+div:first-child + div {
+ height: 100px;
+ width: 100px;
+ margin-left: 200px;
+ background: blue;
+ display: inline-block;
+}
+ </style>
+ <script type="text/javascript">
+//this test enforces the following spec statement:
+//"if this immediate user selection is not the same as the current target element"
+window.onload = function () {
+ var drag = document.getElementsByTagName('div')[0], sequence = [];
+ drag.ondragstart = function (e) {
+ e.dataTransfer.setData('text','hello');
+ e.dataTransfer.effectAllowed = 'copy';
+ };
+ drag.ondragenter = function (e) {
+ sequence[sequence.length] = 'drag.dragenter';
+ };
+ drag.ondragover = function (e) {
+ if( sequence[sequence.length-1] != 'drag.dragover' ) {
+ sequence[sequence.length] = 'drag.dragover';
+ }
+ };
+ var drop = document.getElementsByTagName('div')[1];
+ drop.ondragenter = function (e) {
+ e.preventDefault();
+ sequence[sequence.length] = 'drop.dragenter';
+ };
+ drop.ondragover = function (e) {
+ e.preventDefault();
+ if( sequence[sequence.length-1] != 'drop.dragover' ) {
+ sequence[sequence.length] = 'drop.dragover';
+ }
+ };
+ drop.ondrop = function (e) {
+ e.preventDefault();
+ sequence[sequence.length] = 'drop.ondrop';
+ };
+ document.body.ondragenter = function (e) {
+ sequence[sequence.length] = ( e.target == this ) ? 'body.dragenter' : 'bubble.dragenter';
+ };
+ document.body.ondragover = function (e) {
+ if( e.target != this ) { return; }
+ if( sequence[sequence.length-1] != 'body.dragover' ) {
+ sequence[sequence.length] = 'body.dragover';
+ }
+ };
+ drag.ondragend = function (e) {
+ sequence = sequence.join('=&gt;')
+ var desiredsequence = (['drag.dragenter','bubble.dragenter','body.dragenter','body.dragover','drop.dragenter','bubble.dragenter','drop.dragover','drop.ondrop']).join('=&gt;')
+ if( sequence == desiredsequence ) {
+ document.getElementsByTagName('div')[2].innerHTML = 'PASS';
+ } else {
+ document.getElementsByTagName('div')[2].innerHTML = 'FAIL, got:<br>'+sequence+'<br>instead of:<br>'+desiredsequence;
+ }
+ };
+};
+ </script>
+ </head>
+ <body>
+
+ <div draggable="true"></div><div></div>
+ <div>&nbsp;</div>
+ <p>Drag the orange square onto the blue square and release it.</p>
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/033.html b/testing/web-platform/tests/html/editing/dnd/events/033.html
new file mode 100644
index 0000000000..d06bee3d8d
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/033.html
@@ -0,0 +1,79 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Drag and drop without cancelling dragenter from non-target to non-target</title>
+ <style type="text/css">
+div:first-child {
+ height: 100px;
+ width: 100px;
+ background: orange;
+ display: inline-block;
+}
+div:first-child + div {
+ height: 100px;
+ width: 100px;
+ background: blue;
+ display: inline-block;
+}
+ </style>
+ <script type="text/javascript">
+window.onload = function () {
+ var drag = document.getElementsByTagName('div')[0], sequence = [];
+ drag.ondragstart = function (e) {
+ e.dataTransfer.setData('text','hello');
+ e.dataTransfer.effectAllowed = 'copy';
+ };
+ drag.ondragenter = function (e) {
+ sequence[sequence.length] = 'drag.dragenter';
+ };
+ drag.ondragover = function (e) {
+ if( sequence[sequence.length-1] != 'drag.dragover' ) {
+ sequence[sequence.length] = 'drag.dragover';
+ }
+ };
+ drag.ondragleave = function (e) {
+ sequence[sequence.length] = 'drag.dragleave';
+ };
+ var drop = document.getElementsByTagName('div')[1];
+ drop.ondragenter = function (e) {
+ sequence[sequence.length] = 'drop.dragenter';
+ };
+ drop.ondragover = function (e) {
+ if( sequence[sequence.length-1] != 'drop.dragover' ) {
+ sequence[sequence.length] = 'drop.dragover';
+ }
+ };
+ drop.ondrop = function (e) {
+ e.preventDefault();
+ sequence[sequence.length] = 'drop.ondrop';
+ };
+ document.body.ondragenter = function (e) {
+ sequence[sequence.length] = ( e.target == this ) ? 'body.dragenter' : 'bubble.dragenter';
+ };
+ document.body.ondragover = function (e) {
+ if( e.target != this ) { return; }
+ if( sequence[sequence.length-1] != 'body.dragover' ) {
+ sequence[sequence.length] = 'body.dragover';
+ }
+ };
+ drag.ondragend = function (e) {
+ sequence = sequence.join('=&gt;')
+ var desiredsequence = (['drag.dragenter','bubble.dragenter','body.dragenter','body.dragover','drop.dragenter','bubble.dragenter','body.dragover']).join('=&gt;')
+ if( sequence == desiredsequence ) {
+ document.getElementsByTagName('div')[2].innerHTML = 'PASS';
+ } else {
+ document.getElementsByTagName('div')[2].innerHTML = 'FAIL, got:<br>'+sequence+'<br>instead of:<br>'+desiredsequence;
+ }
+ };
+};
+ </script>
+ </head>
+ <body>
+
+ <div draggable="true"></div><div></div>
+ <div>&nbsp;</div>
+ <p>Drag the orange square onto the blue square and release it.</p>
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/034.html b/testing/web-platform/tests/html/editing/dnd/events/034.html
new file mode 100644
index 0000000000..ea8867ba2c
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/034.html
@@ -0,0 +1,56 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Drag and drop with cancelling dragenter on body</title>
+ <style type="text/css">
+div:first-child {
+ height: 100px;
+ width: 100px;
+ background: orange;
+ display: inline-block;
+}
+div:first-child + div {
+ height: 100px;
+ width: 100px;
+ margin-left: 100px;
+ background: blue;
+ display: inline-block;
+}
+ </style>
+ <script type="text/javascript">
+window.onload = function () {
+ var drag = document.getElementsByTagName('div')[0], beforecount = 0, aftercount = 0, switchcount = false;
+ drag.ondragstart = function (e) {
+ e.dataTransfer.setData('text','hello');
+ e.dataTransfer.effectAllowed = 'copy';
+ };
+ drag.ondragenter = drag.ondrop = drag.ondragover = function (e) {
+ e.preventDefault();
+ };
+ var drop = document.getElementsByTagName('div')[1];
+ drop.ondragenter = function (e) {
+ switchcount = true;
+ };
+ drop.ondragover = function (e) {
+ e.preventDefault();
+ };
+ document.body.ondragenter = function (e) {
+ if( e.target != this ) { return; }
+ e.preventDefault(); //don't cancel when it bubbles from the child elements
+ if( switchcount ) { aftercount++; } else { beforecount++; }
+ };
+ drag.ondragend = function (e) {
+ document.getElementsByTagName('div')[2].innerHTML = ( beforecount == 1 && aftercount == 0 ) ? 'PASS' : ( 'FAIL, dragenter fired on body '+beforecount+' time(s) before blue.ondragenter and '+aftercount+' time(s) afterwards, instead of 1 and 0 times respectively' );
+ };
+};
+ </script>
+ </head>
+ <body>
+
+ <div draggable="true"></div><div></div>
+ <div>&nbsp;</div>
+ <p>Drag the orange square onto the blue square, then back to the orange square, and release it.</p>
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/035.html b/testing/web-platform/tests/html/editing/dnd/events/035.html
new file mode 100644
index 0000000000..8a7cb17491
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/035.html
@@ -0,0 +1,83 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Drag and drop passing over body with cancelling dragenter</title>
+ <style type="text/css">
+div:first-child {
+ height: 100px;
+ width: 100px;
+ background: orange;
+ display: inline-block;
+}
+div:first-child + div {
+ height: 100px;
+ width: 100px;
+ margin-left: 200px;
+ background: blue;
+ display: inline-block;
+}
+ </style>
+ <script type="text/javascript">
+//this test enforces the following spec statement:
+//"if this immediate user selection is not the same as the current target element"
+window.onload = function () {
+ var drag = document.getElementsByTagName('div')[0], sequence = [];
+ drag.ondragstart = function (e) {
+ e.dataTransfer.setData('text','hello');
+ e.dataTransfer.effectAllowed = 'copy';
+ };
+ drag.ondragenter = function (e) {
+ sequence[sequence.length] = 'drag.dragenter';
+ };
+ drag.ondragover = function (e) {
+ if( sequence[sequence.length-1] != 'drag.dragover' ) {
+ sequence[sequence.length] = 'drag.dragover';
+ }
+ };
+ var drop = document.getElementsByTagName('div')[1];
+ drop.ondragenter = function (e) {
+ e.preventDefault();
+ sequence[sequence.length] = 'drop.dragenter';
+ };
+ drop.ondragover = function (e) {
+ e.preventDefault();
+ if( sequence[sequence.length-1] != 'drop.dragover' ) {
+ sequence[sequence.length] = 'drop.dragover';
+ }
+ };
+ drop.ondrop = function (e) {
+ e.preventDefault();
+ sequence[sequence.length] = 'drop.ondrop';
+ };
+ document.body.ondragenter = function (e) {
+ sequence[sequence.length] = ( e.target == this ) ? 'body.dragenter' : 'bubble.dragenter';
+ if( e.target != this ) { return; }
+ e.preventDefault(); //don't cancel when it bubbles from the child elements
+ };
+ document.body.ondragover = function (e) {
+ if( e.target != this ) { return; }
+ if( sequence[sequence.length-1] != 'body.dragover' ) {
+ sequence[sequence.length] = 'body.dragover';
+ }
+ };
+ drag.ondragend = function (e) {
+ sequence = sequence.join('=&gt;')
+ var desiredsequence = (['drag.dragenter','bubble.dragenter','body.dragenter','body.dragover','drop.dragenter','bubble.dragenter','drop.dragover','drop.ondrop']).join('=&gt;')
+ if( sequence == desiredsequence ) {
+ document.getElementsByTagName('div')[2].innerHTML = 'PASS';
+ } else {
+ document.getElementsByTagName('div')[2].innerHTML = 'FAIL, got:<br>'+sequence+'<br>instead of:<br>'+desiredsequence;
+ }
+ };
+};
+ </script>
+ </head>
+ <body>
+
+ <div draggable="true"></div><div></div>
+ <div>&nbsp;</div>
+ <p>Drag the orange square onto the blue square and release it.</p>
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/036.html b/testing/web-platform/tests/html/editing/dnd/events/036.html
new file mode 100644
index 0000000000..1c66f18483
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/036.html
@@ -0,0 +1,70 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Drag and drop passing over body with all events handled at body</title>
+ <style type="text/css">
+div:first-child {
+ height: 100px;
+ width: 100px;
+ background: orange;
+ display: inline-block;
+}
+div:first-child + div {
+ height: 100px;
+ width: 100px;
+ margin-left: 200px;
+ background: blue;
+ display: inline-block;
+}
+ </style>
+ <script type="text/javascript">
+window.onload = function () {
+ var drag = document.getElementsByTagName('div')[0], drop = document.getElementsByTagName('div')[1], sequence = [];
+ function targ(el) {
+ if( el == drag ) { return 'drag'; }
+ else if( el == drop ) { return 'drop'; }
+ else if( el == document.body ) { return 'body'; }
+ else { return el; }
+ }
+ document.body.ondragstart = function (e) {
+ e.dataTransfer.setData('text','data');
+ e.dataTransfer.effectAllowed = 'copy';
+ };
+ document.body.ondragenter = function (e) {
+ e.preventDefault();
+ sequence[sequence.length] = targ(e.target)+'.ondragenter';
+ };
+ document.body.ondragover = function (e) {
+ e.preventDefault();
+ var seqname = targ(e.target)+'.ondragover';
+ if( sequence[sequence.length-1] != seqname ) {
+ sequence[sequence.length] = seqname;
+ }
+ };
+ document.body.ondrop = function (e) {
+ e.preventDefault();
+ sequence[sequence.length] = targ(e.target)+'.ondrop';
+ sequence[sequence.length] = e.dataTransfer.getData('text');
+ };
+ document.body.ondragend = function (e) {
+ sequence[sequence.length] = targ(e.target)+'.ondragend';
+ sequence = sequence.join('=&gt;')
+ var desiredsequence = (['drag.ondragenter','drag.ondragover','body.ondragenter','body.ondragover','drop.ondragenter','drop.ondragover','drop.ondrop','data','drag.ondragend']).join('=&gt;')
+ if( sequence == desiredsequence ) {
+ document.getElementsByTagName('div')[2].innerHTML = 'PASS';
+ } else {
+ document.getElementsByTagName('div')[2].innerHTML = 'FAIL, got:<br>'+sequence+'<br>instead of:<br>'+desiredsequence;
+ }
+ };
+};
+ </script>
+ </head>
+ <body>
+
+ <div draggable="true"></div><div></div>
+ <div>&nbsp;</div>
+ <p>Drag the orange square onto the blue square and release it. For the entire duration of the drag, if supported by the platform, the mouse cursor should show as a drop-allowed or drop-copy-allowed cursor.</p>
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/037-proposed.xhtml b/testing/web-platform/tests/html/editing/dnd/events/037-proposed.xhtml
new file mode 100644
index 0000000000..3c94177f02
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/037-proposed.xhtml
@@ -0,0 +1,86 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Drag and drop without cancelling dragenter and without body</title>
+ <style type="text/css">
+html {
+ padding:20px;
+}
+head + div {
+ height: 100px;
+ width: 100px;
+ background: orange;
+ display: inline-block;
+}
+head + div + div {
+ height: 100px;
+ width: 100px;
+ margin-left: 100px;
+ background: blue;
+ display: inline-block;
+}
+ </style>
+ <script type="text/javascript"><![CDATA[
+//Drag passes from orange to root element. Dragenter fires at root element.
+//Dragenter is not cancelled. Body does not exist. Dragenter fires at root element again.
+//Drag passes from root element to blue. Dragenter fires at blue.
+//Dragenter is not cancelled. Body does not exist. Current target element is root element.
+//Drag passes from blue to root element. Current target element is already root element.
+//Drag passes from root element to orange. Dragenter fires at orange, and is cancelled.
+window.onload = function () {
+ var orange = document.getElementsByTagName('div')[0], sequence = [];
+ orange.ondragstart = function (e) {
+ e.dataTransfer.setData('text','hello');
+ e.dataTransfer.effectAllowed = 'copy';
+ };
+ orange.ondragenter = orange.ondrop = function (e) {
+ sequence[sequence.length] = 'orange.'+e.type;
+ e.preventDefault();
+ };
+ orange.ondragleave = function (e) {
+ sequence[sequence.length] = 'orange.dragleave';
+ };
+ orange.ondragover = function (e) {
+ if( sequence[sequence.length-1] != 'orange.dragover' ) {
+ sequence[sequence.length] = 'orange.dragover';
+ }
+ e.preventDefault();
+ };
+ var blue = document.getElementsByTagName('div')[1];
+ blue.ondragenter = blue.ondragover = blue.ondragleave = function (e) {
+ sequence[sequence.length] = 'blue.'+e.type;
+ };
+ document.documentElement.ondragenter = document.documentElement.ondragleave = function (e) {
+ if( e.target != this ) { return; }
+ sequence[sequence.length] = 'html.'+e.type;
+ };
+ document.documentElement.ondragover = function (e) {
+ if( e.target != this ) { return; }
+ if( sequence[sequence.length-1] != 'html.dragover' ) {
+ sequence[sequence.length] = 'html.dragover';
+ }
+ };
+ document.ondragenter = document.ondragleave = document.ondragover = document.ondragleave = function (e) {
+ if( e.target != this ) { return; }
+ sequence[sequence.length] = 'document.'+e.type;
+ };
+ orange.ondragend = function (e) {
+ sequence = sequence.join('=>')
+ var desiredsequence = (['orange.dragenter','orange.dragover','html.dragenter','html.dragenter','orange.dragleave','html.dragover','blue.dragenter','html.dragover','orange.dragenter','html.dragleave','orange.dragover','orange.drop']).join('=>')
+ if( sequence == desiredsequence ) {
+ document.getElementsByTagName('div')[2].textContent = 'PASS';
+ } else {
+ document.getElementsByTagName('div')[2].textContent = 'FAIL, got: '+sequence+' instead of: '+desiredsequence;
+ }
+ };
+};
+ ]]></script>
+ </head>
+ <!--body-->
+
+ <div draggable="true"></div><div></div>
+ <div>&#160;</div>
+ <p>Drag the orange square onto the blue square, then back to the orange square, and release it.</p>
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+
+ <!--/body-->
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/037-spec.xhtml b/testing/web-platform/tests/html/editing/dnd/events/037-spec.xhtml
new file mode 100644
index 0000000000..c4c76fe806
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/037-spec.xhtml
@@ -0,0 +1,88 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Drag and drop without cancelling dragenter and without body (spec compliant)</title>
+ <style type="text/css">
+head + div {
+ height: 100px;
+ width: 100px;
+ background: orange;
+ display: inline-block;
+}
+head + div + div {
+ height: 100px;
+ width: 100px;
+ margin-left: 100px;
+ background: blue;
+ display: inline-block;
+}
+ </style>
+ <script type="text/javascript"><![CDATA[
+//Drag passes from orange to root element. Dragenter fires at root element.
+//Dragenter is not cancelled. Body does not exist. Dragenter fires at document.
+//Spec says the body (which does not exist) becomes current target element => null.
+//Drag passes from root element to blue. Dragenter fires at blue.
+//Dragenter is not cancelled. Body does not exist. Current target element is null.
+//Dragenter fires at document. Current target is set to null again.
+//Drag passes from blue to root element. Dragenter fires at root element.
+//Dragenter is not cancelled. Body does not exist. Current target element is null.
+//Dragenter is not cancelled. Body does not exist. Dragenter fires at document.
+//Current target is set to null. Yet again.
+//Drag passes from root element to orange. Dragenter fires at orange, and is cancelled.
+window.onload = function () {
+ var orange = document.getElementsByTagName('div')[0], sequence = [];
+ orange.ondragstart = function (e) {
+ e.dataTransfer.setData('text','hello');
+ e.dataTransfer.effectAllowed = 'copy';
+ };
+ orange.ondragenter = orange.ondrop = function (e) {
+ sequence[sequence.length] = 'orange.'+e.type;
+ e.preventDefault();
+ };
+ orange.ondragleave = function (e) {
+ sequence[sequence.length] = 'orange.dragleave';
+ };
+ orange.ondragover = function (e) {
+ if( sequence[sequence.length-1] != 'orange.dragover' ) {
+ sequence[sequence.length] = 'orange.dragover';
+ }
+ e.preventDefault();
+ };
+ var blue = document.getElementsByTagName('div')[1];
+ blue.ondragenter = blue.ondragover = blue.ondragleave = function (e) {
+ sequence[sequence.length] = 'blue.'+e.type;
+ };
+ document.documentElement.ondragenter = document.documentElement.ondragleave = function (e) {
+ if( e.target != this ) { return; }
+ sequence[sequence.length] = 'html.'+e.type;
+ };
+ document.documentElement.ondragover = function (e) {
+ if( e.target != this ) { return; }
+ if( sequence[sequence.length-1] != 'html.dragover' ) {
+ sequence[sequence.length] = 'html.dragover';
+ }
+ };
+ document.ondragenter = document.ondragleave = document.ondragover = document.ondragleave = function (e) {
+ if( e.target != this ) { return; }
+ sequence[sequence.length] = 'document.'+e.type;
+ };
+ orange.ondragend = function (e) {
+ sequence = sequence.join('=>')
+ var desiredsequence = (['orange.dragenter','orange.dragover','html.dragenter','document.dragenter','orange.dragleave','blue.dragenter','document.dragenter','document.dragenter','orange.dragenter','orange.dragover','orange.drop']).join('=>')
+ if( sequence == desiredsequence ) {
+ document.getElementsByTagName('div')[2].textContent = 'PASS';
+ } else {
+ document.getElementsByTagName('div')[2].textContent = 'FAIL, got: '+sequence+' instead of: '+desiredsequence;
+ }
+ };
+};
+ ]]></script>
+ </head>
+ <!--body-->
+
+ <div draggable="true"></div><div></div>
+ <div>&#160;</div>
+ <p>Drag the orange square onto the blue square, then back to the orange square, and release it.</p>
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+
+ <!--/body-->
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/038-proposed.html b/testing/web-platform/tests/html/editing/dnd/events/038-proposed.html
new file mode 100644
index 0000000000..ee1cc8ed0e
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/038-proposed.html
@@ -0,0 +1,84 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Drag and drop without cancelling dragenter and without body or html</title>
+ <style type="text/css">
+body > div:first-child {
+ height: 100px;
+ width: 100px;
+ background: orange;
+ display: inline-block;
+}
+iframe {
+ height: 100px;
+ width: 100px;
+ margin-left: 100px;
+ display: inline-block;
+ border: none;
+}
+ </style>
+ <script type="text/javascript">
+//Drag passes from parent to blue. Dragenter fires at blue. Root element is deleted.
+//Dragenter is not cancelled. Body does not exist. Root element does not exist.
+//Current target element is set to null. Drag now points at unrendered document - null.
+//Current target element remains null.
+//Drag passes over parent to orange. Dragenter fires at orange, and is cancelled.
+window.onload = function () {
+ var orange = document.getElementsByTagName('div')[0], sequence = [];
+ orange.ondragstart = function (e) {
+ e.dataTransfer.setData('text','hello');
+ e.dataTransfer.effectAllowed = 'copy';
+ };
+ orange.ondragenter = orange.ondrop = function (e) {
+ sequence[sequence.length] = 'orange.'+e.type;
+ e.preventDefault();
+ };
+ orange.ondragleave = function (e) {
+ sequence[sequence.length] = 'orange.dragleave';
+ };
+ orange.ondragover = function (e) {
+ if( sequence[sequence.length-1] != 'orange.dragover' ) {
+ sequence[sequence.length] = 'orange.dragover';
+ }
+ e.preventDefault();
+ };
+ var blue = document.getElementsByTagName('iframe')[0].contentDocument;
+ if( !blue.documentElement ) { blue.appendChild(blue.createElement('html')); }
+ blue.documentElement.style.margin = '0';
+ blue.documentElement.style.padding = '0';
+ if( !blue.body ) { blue.documentElement.appendChild(blue.createElement('body')); }
+ blue.body.style.margin = '0';
+ blue.body.style.padding = '0';
+ var bluediv = blue.body.appendChild(blue.createElement('div'));
+ bluediv.style.height = '100px';
+ bluediv.style.width = '100px';
+ bluediv.style.background = 'blue';
+ bluediv.ondragenter = bluediv.ondragover = function (e) {
+ sequence[sequence.length] = 'blue.'+e.type;
+ if( blue.documentElement ) { blue.removeChild(blue.documentElement); }
+ };
+ blue.ondragenter = blue.ondragover = blue.ondragleave = function (e) {
+ if( e.target != this ) { return; }
+ sequence[sequence.length] = 'bluedocument.'+e.type;
+ };
+ orange.ondragend = function (e) {
+ sequence = sequence.join('=&gt;')
+ var desiredsequence = (['orange.dragenter','orange.dragover','orange.dragleave','blue.dragenter','orange.dragenter','orange.dragover','orange.drop']).join('=&gt;')
+ if( sequence == desiredsequence ) {
+ document.getElementsByTagName('div')[1].innerHTML = 'PASS';
+ } else {
+ document.getElementsByTagName('div')[1].innerHTML = 'FAIL, got:<br>'+sequence+'<br>instead of:<br>'+desiredsequence;
+ }
+ };
+};
+ </script>
+ </head>
+ <body>
+
+ <div draggable="true"></div><iframe src="about:blank"></iframe>
+ <div>&nbsp;</div>
+ <p>Drag the orange square onto the blue square, then back to the orange square, and release it.</p>
+ <noscript><p>Enable JavaScript and reload</p></noscript>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/drag-event-div-manual.html b/testing/web-platform/tests/html/editing/dnd/events/drag-event-div-manual.html
new file mode 100644
index 0000000000..79c0c4332d
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/drag-event-div-manual.html
@@ -0,0 +1,62 @@
+<!doctype html>
+<html>
+ <head>
+ <title>HTML5 Drag and Drop: Fire drag event when dragging a div element</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <link rel="help" href="http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model"/>
+ <meta name="assert" content="Fire drag event when dragging a div element"/>
+ <script src="../resources/dragdrop_support.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ var EVENT, TARGET;
+
+ function DragEvent(evt)
+ {
+ if ((TARGET == evt.target) && (EVENT == evt.type))
+ {
+ LogTestResult("PASS");
+ }
+ else
+ {
+ LogTestResult("FAIL");
+ }
+ }
+
+ EVENT = "drag";
+
+ window.onload = function()
+ {
+ TARGET = document.getElementById("target");
+ AddEventListenersForElement(EVENT, DragEvent, false, TARGET);
+ }
+ </script>
+ </head>
+ <body>
+ <pre>Description: Fire drag event when dragging a div element</pre>
+ <table id='testtable' border='1'>
+ <tr>
+ <td>Test Result</td>
+ <td>Test Assertion</td>
+ </tr>
+ <tr>
+ <td id='test_result'>Manual</td>
+ <td id='test_assertion'>Test passes if if the word "PASS" appears to the left after following the steps below.
+ <div id="manualsteps">
+ Steps:
+ <ol>
+ <li> Click and drag the red box
+ </ol>
+ </div>
+ </td>
+ </tr>
+ </table>
+ <p>
+ http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model
+ </p>
+ <p>
+ If the user agent is still performing the previous iteration of the sequence (if any) when the next iteration becomes due, abort these steps for this iteration (effectively "skipping missed frames" of the drag-and-drop operation).
+ Fire a DND event named drag event at the source node. If this event is canceled, the user agent must set the current drag operation to "none" (no drag operation).
+ </p>
+ <div id="target" style="border:2px red solid; width:200px; height:50px" draggable="true"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/drag-event-manual.html b/testing/web-platform/tests/html/editing/dnd/events/drag-event-manual.html
new file mode 100644
index 0000000000..d278b864bb
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/drag-event-manual.html
@@ -0,0 +1,62 @@
+<!doctype html>
+<html>
+ <head>
+ <title>HTML5 Drag and Drop: Fire drag event during the drag and drop processing</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <link rel="help" href="http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model"/>
+ <meta name="assert" content="Fire drag event during the drag and drop processing"/>
+ <script src="../resources/dragdrop_support.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ var EVENT, TARGET;
+
+ function DragEvent(evt)
+ {
+ if ((TARGET == evt.target) && (EVENT == evt.type))
+ {
+ LogTestResult("PASS");
+ }
+ else
+ {
+ LogTestResult("FAIL");
+ }
+ }
+
+ EVENT = "drag";
+
+ window.onload = function()
+ {
+ TARGET = document.getElementById("target");
+ AddEventListenersForElement(EVENT, DragEvent, false, TARGET);
+ }
+ </script>
+ </head>
+ <body>
+ <pre>Description: Fire drag event during the drag and drop processing</pre>
+ <table id='testtable' border='1'>
+ <tr>
+ <td>Test Result</td>
+ <td>Test Assertion</td>
+ </tr>
+ <tr>
+ <td id='test_result'>Manual</td>
+ <td id='test_assertion'>Test passes if if the word "PASS" appears to the left after following the steps below.
+ <div id="manualsteps">
+ Steps:
+ <ol>
+ <li> Click and drag the blue image
+ </ol>
+ </div>
+ </td>
+ </tr>
+ </table>
+ <p>
+ http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model
+ </p>
+ <p>
+ If the user agent is still performing the previous iteration of the sequence (if any) when the next iteration becomes due, abort these steps for this iteration (effectively "skipping missed frames" of the drag-and-drop operation).
+ Fire a DND event named drag event at the source node. If this event is canceled, the user agent must set the current drag operation to "none" (no drag operation).
+ </p>
+ <img src="/images/blue.png" style="width:200px; height:100px" draggable="true" id="target"/>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/dragend-event-manual.html b/testing/web-platform/tests/html/editing/dnd/events/dragend-event-manual.html
new file mode 100644
index 0000000000..8bfb1fb7b6
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/dragend-event-manual.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<html>
+ <head>
+ <title>HTML5 Drag and Drop: Fire dragend event during the drag and drop processing</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <link rel="help" href="http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model"/>
+ <meta name="assert" content="Fire dragend event during the drag and drop processing"/>
+ <script src="../resources/dragdrop_support.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ var EVENT, TARGET;
+
+ function DragendEvent(evt)
+ {
+ if ((TARGET == evt.target) && (EVENT == evt.type))
+ {
+ LogTestResult("PASS");
+ }
+ else
+ {
+ LogTestResult("FAIL");
+ }
+ }
+
+ EVENT = "dragend";
+
+ window.onload = function()
+ {
+ TARGET = document.getElementById("target");
+ AddEventListenersForElement(EVENT, DragendEvent, false, TARGET);
+ }
+ </script>
+ </head>
+ <body>
+ <pre>Description: Fire dragend event during the drag and drop processing</pre>
+ <table id='testtable' border='1'>
+ <tr>
+ <td>Test Result</td>
+ <td>Test Assertion</td>
+ </tr>
+ <tr>
+ <td id='test_result'>Manual</td>
+ <td id='test_assertion'>Test passes if if the word "PASS" appears to the left after following the steps below.
+ <div id="manualsteps">
+ Steps:
+ <ol>
+ <li> Drag the blue image
+ <li> Drop it on the green box
+ </ol>
+ </div>
+ </td>
+ </tr>
+ </table>
+ <p>
+ http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model
+ </p>
+ <p>
+ If the drag operation failed or succeeded, fire a DND event named dragend at the source node.
+ </p>
+ <img src="/images/blue.png" style="width:200px; height:100px" draggable="true" id="target"/>
+ <br /><br />
+ <input type="text" style="border:2px green solid; width:200px; height:50px"></input>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/dragenter-event-manual.html b/testing/web-platform/tests/html/editing/dnd/events/dragenter-event-manual.html
new file mode 100644
index 0000000000..e81b32949c
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/dragenter-event-manual.html
@@ -0,0 +1,67 @@
+<!doctype html>
+<html>
+ <head>
+ <title>HTML5 Drag and Drop: Fire dragenter event during the drag and drop processing</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <link rel="help" href="http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model"/>
+ <meta name="assert" content="Fire dragenter event during the drag and drop processing"/>
+ <script src="../resources/dragdrop_support.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ var EVENT, TARGET;
+
+ function DragenterEvent(evt)
+ {
+ if ((TARGET == evt.target) && (EVENT == evt.type))
+ {
+ LogTestResult("PASS");
+ }
+ else
+ {
+ LogTestResult("FAIL");
+ }
+ }
+
+ EVENT = "dragenter";
+
+ window.onload = function()
+ {
+ TARGET = document.getElementById("target");
+ AddEventListenersForElement(EVENT, DragenterEvent, false, TARGET);
+ }
+ </script>
+ </head>
+ <body>
+ <pre>Description: Fire dragenter event during the drag and drop processing</pre>
+ <table id='testtable' border='1'>
+ <tr>
+ <td>Test Result</td>
+ <td>Test Assertion</td>
+ </tr>
+ <tr>
+ <td id='test_result'>Manual</td>
+ <td id='test_assertion'>Test passes if if the word "PASS" appears to the left after following the steps below.
+ <div id="manualsteps">
+ Steps:
+ <ol>
+ <li> Select the text inside the red box
+ <li> Drag it and enter the green box
+ </ol>
+ </div>
+ </td>
+ </tr>
+ </table>
+ <p>
+ http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model
+ </p>
+ <p>
+ If the user is indicating a different immediate user selection than during the last iteration (or if this is the first iteration), and if this immediate user selection is not the same as the current target element, then update the current target element as follows:
+ - If the new immediate user selection is null, Set the current target element to null also.
+ - If the new immediate user selection is in a non-DOM document or application, Set the current target element to the immediate user selection.
+ - Otherwise, Fire a DND event named dragenter at the immediate user selection.
+ </p>
+ <div style="border:2px red solid; width:200px; height:50px">SampleText</div>
+ <br /><br />
+ <input type="text" id="target" style="border:2px green solid; width:200px; height:50px"></input>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/dragleave-event-manual.html b/testing/web-platform/tests/html/editing/dnd/events/dragleave-event-manual.html
new file mode 100644
index 0000000000..f6a405915f
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/dragleave-event-manual.html
@@ -0,0 +1,66 @@
+<!doctype html>
+<html>
+ <head>
+ <title>HTML5 Drag and Drop: Fire dragleave event during the drag and drop processing</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <link rel="help" href="http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model"/>
+ <meta name="assert" content="Fire dragleave event during the drag and drop processing"/>
+ <script src="../resources/dragdrop_support.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ var EVENT, TARGET;
+
+ function DragleaveEvent(evt)
+ {
+ if ((TARGET == evt.target) && (EVENT == evt.type))
+ {
+ LogTestResult("PASS");
+ }
+ else
+ {
+ LogTestResult("FAIL");
+ }
+ }
+
+ EVENT = "dragleave";
+
+ window.onload = function()
+ {
+ TARGET = document.getElementById("target");
+ AddEventListenersForElement(EVENT, DragleaveEvent, false, TARGET);
+ }
+ </script>
+ </head>
+ <body>
+ <pre>Description: Fire dragleave event during the drag and drop processing</pre>
+ <table id='testtable' border='1'>
+ <tr>
+ <td>Test Result</td>
+ <td>Test Assertion</td>
+ </tr>
+ <tr>
+ <td id='test_result'>Manual</td>
+ <td id='test_assertion'>Test passes if if the word "PASS" appears to the left after following the steps below.
+ <div id="manualsteps">
+ Steps:
+ <ol>
+ <li> Select the text inside the red box
+ <li> Drag it over the blue box and drop it on the green box
+ </ol>
+ </div>
+ </td>
+ </tr>
+ </table>
+ <p>
+ http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model
+ </p>
+ <p>
+ If there is a change in the current target element, and if the previous target element was not null or a part of a non-DOM document, then fire a DND event named dragleave at the previous target element.
+ </p>
+ <div style="border:2px red solid; width:100px">SampleText</div>
+ <br />
+ <div id="target" style="border:2px blue solid; width:200px; height:50px"></div>
+ <br />
+ <input type="text" style="border:2px green solid; width:200px; height:50px"></input>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/dragover-event-manual.html b/testing/web-platform/tests/html/editing/dnd/events/dragover-event-manual.html
new file mode 100644
index 0000000000..f8d99241d5
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/dragover-event-manual.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<html>
+ <head>
+ <title>HTML5 Drag and Drop: Fire dragover event during the drag and drop processing</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <link rel="help" href="http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model"/>
+ <meta name="assert" content="Fire dragover event during the drag and drop processing"/>
+ <script src="../resources/dragdrop_support.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ var EVENT, TARGET;
+
+ function DragoverEvent(evt)
+ {
+ if ((TARGET == evt.target) && (EVENT == evt.type))
+ {
+ LogTestResult("PASS");
+ }
+ else
+ {
+ LogTestResult("FAIL");
+ }
+ }
+
+ EVENT = "dragover";
+
+ window.onload = function()
+ {
+ TARGET = document.getElementById("target");
+ AddEventListenersForElement(EVENT, DragoverEvent, false, TARGET);
+ }
+ </script>
+ </head>
+ <body>
+ <pre>Description: Fire dragover event during the drag and drop processing</pre>
+ <table id='testtable' border='1'>
+ <tr>
+ <td>Test Result</td>
+ <td>Test Assertion</td>
+ </tr>
+ <tr>
+ <td id='test_result'>Manual</td>
+ <td id='test_assertion'>Test passes if if the word "PASS" appears to the left after following the steps below.
+ <div id="manualsteps">
+ Steps:
+ <ol>
+ <li> Select the text inside the red box.
+ <li> Drag it, hover over the green box and then release the mouse
+ </ol>
+ </div>
+ </td>
+ </tr>
+ </table>
+ <p>
+ http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model
+ </p>
+ <p>
+ If the current target element is a DOM element, then fire a DND event named dragover at this current target element
+ </p>
+ <div style="border:2px red solid; width:100px">SampleText</div>
+ <br /><br />
+ <div id="target" style="border:2px green solid; width:200px; height:100px"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/dragstart-event-manual.html b/testing/web-platform/tests/html/editing/dnd/events/dragstart-event-manual.html
new file mode 100644
index 0000000000..20786648da
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/dragstart-event-manual.html
@@ -0,0 +1,62 @@
+<!doctype html>
+<html>
+ <head>
+ <title>HTML5 Drag and Drop: Fire dragstart event during the drag and drop processing</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <link rel="help" href="http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model"/>
+ <meta name="assert" content="Fire dragstart event during the drag and drop processing"/>
+ <script src="../resources/dragdrop_support.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ var EVENT, TARGET;
+
+ function DragstartEvent(evt)
+ {
+ if ((TARGET == evt.target) && (EVENT == evt.type))
+ {
+ LogTestResult("PASS");
+ }
+ else
+ {
+ LogTestResult("FAIL");
+ }
+ }
+
+ EVENT = "dragstart";
+
+ window.onload = function()
+ {
+ TARGET = document.getElementById("target");
+ AddEventListenersForElement(EVENT, DragstartEvent, false, TARGET);
+ }
+ </script>
+ </head>
+ <body>
+ <pre>Description: Fire dragstart event during the drag and drop processing</pre>
+ <table id='testtable' border='1'>
+ <tr>
+ <td>Test Result</td>
+ <td>Test Assertion</td>
+ </tr>
+ <tr>
+ <td id='test_result'>Manual</td>
+ <td id='test_assertion'>Test passes if if the word "PASS" appears to the left after following the steps below.
+ <div id="manualsteps">
+ Steps:
+ <ol>
+ <li> Click and drag the red box
+ </ol>
+ </div>
+ </td>
+ </tr>
+ </table>
+ <p>
+ http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model
+ </p>
+ <p>
+ If it is an element that is being dragged, then set the drag data store elements list to contain just the source node.
+ Fire a DND event named dragstart at the source node.
+ </p>
+ <div id="target" style="border:2px red solid; width:200px; height:50px" draggable="true"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/drop-event-manual.html b/testing/web-platform/tests/html/editing/dnd/events/drop-event-manual.html
new file mode 100644
index 0000000000..2897bd5713
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/drop-event-manual.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<html>
+ <head>
+ <title>HTML5 Drag and Drop: Fire drop event during the drag and drop processing</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <link rel="help" href="http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model"/>
+ <meta name="assert" content="Fire drop event during the drag and drop processing"/>
+ <script src="../resources/dragdrop_support.js" type="text/javascript"></script>
+ <script type="text/javascript">
+ var EVENT, TARGET;
+
+ function DropEvent(evt)
+ {
+ if ((TARGET == evt.target) && (EVENT == evt.type))
+ {
+ LogTestResult("PASS");
+ }
+ else
+ {
+ LogTestResult("FAIL");
+ }
+ }
+
+ EVENT = "drop";
+
+ window.onload = function()
+ {
+ TARGET = document.getElementById("target");
+ AddEventListenersForElement(EVENT, DropEvent, false, TARGET);
+ }
+ </script>
+ </head>
+ <body>
+ <pre>Description: Fire drop event during the drag and drop processing</pre>
+ <table id='testtable' border='1'>
+ <tr>
+ <td>Test Result</td>
+ <td>Test Assertion</td>
+ </tr>
+ <tr>
+ <td id='test_result'>Manual</td>
+ <td id='test_assertion'>Test passes if if the word "PASS" appears to the left after following the steps below.
+ <div id="manualsteps">
+ Steps:
+ <ol>
+ <li> Select the text inside the red box
+ <li> Drag it and drop it on the green box
+ </ol>
+ </div>
+ </td>
+ </tr>
+ </table>
+ <p>
+ http://dev.w3.org/html5/spec/dnd.html#drag-and-drop-processing-model
+ </p>
+ <p>
+ If the drag operation was a success, if the current target element is a DOM element, fire a DND event named drop at it.
+ </p>
+ <div style="border:2px red solid; width:100px">SampleText</div>
+ <br /><br />
+ <input type="text" id="target" style="border:2px green solid; width:200px; height:50px"></input>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/events-cross-document-suite-HELPER-1.html b/testing/web-platform/tests/html/editing/dnd/events/events-cross-document-suite-HELPER-1.html
new file mode 100644
index 0000000000..4019610533
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/events-cross-document-suite-HELPER-1.html
@@ -0,0 +1,205 @@
+<!DOCTYPE html>
+<title>drag &amp; drop - event sequence for cross-document drag</title>
+<style type="text/css">
+ /* use margins instead of padding to make sure the body begins at the top of the page */
+ html, body {
+ margin: 0;
+ }
+ body {
+ padding: 116px 8px 8px;
+ }
+ #testhere div {
+ height: 100px;
+ width: 100px;
+ position: absolute;
+ top: 8px;
+ }
+ #orange {
+ background-color: orange;
+ left: 8px;
+ }
+ #fuchsia {
+ background-color: fuchsia;
+ left: 158px;
+ }
+</style>
+
+<script>
+parent.setup(function () {},{explicit_done:true,explicit_timeout:true});
+window.onload = function () {
+ var orange = document.querySelector('#orange')
+ var fuchsia = document.querySelector('#fuchsia')
+ var body = document.body;
+
+ orange.ondragstart = function (e) {
+ parent.events.push('doc1.orange.ondragstart');
+ e.dataTransfer.effectAllowed = 'all';
+ e.dataTransfer.setData('Text', 'foo');
+ };
+ orange.ondrag = function () { parent.events.push('doc1.orange.ondrag'); };
+ orange.ondragenter = function () { parent.events.push('doc1.orange.ondragenter'); };
+ orange.ondragover = function () { parent.events.push('doc1.orange.ondragover'); };
+ orange.ondrop = function () { parent.events.push('doc1.orange.ondrop'); return false; };
+ orange.ondragend = function () { parent.events.push('doc1.orange.ondragend'); setTimeout(finish,100); };
+ orange.onmousedown = function () { parent.events.push('doc1.orange.onmousedown'); };
+ orange.onmouseup = function () { parent.events.push('doc1.orange.onmouseup'); };
+
+ /* Events for the fuchsia box */
+ fuchsia.ondragstart = function () { parent.events.push('doc1.pink.ondragstart'); };
+ fuchsia.ondrag = function () { parent.events.push('doc1.pink.ondrag'); };
+ fuchsia.ondragenter = function () { parent.events.push('doc1.pink.ondragenter'); };
+ fuchsia.ondragover = function () { parent.events.push('doc1.pink.ondragover'); };
+ fuchsia.ondrop = function () { parent.events.push('doc1.pink.ondrop'); return false; };
+ fuchsia.ondragend = function () { parent.events.push('doc1.pink.ondragend'); };
+ fuchsia.onmousedown = function () { parent.events.push('doc1.pink.onmousedown'); };
+ fuchsia.onmouseup = function () { parent.events.push('doc1.pink.onmouseup'); };
+
+ /* Events for the page body */
+ body.ondragstart = function (e) { parent.events.push( ( e.target == body ) ? 'doc1.body.ondragstart': 'doc1.bubble.ondragstart' ); };
+ body.ondrag = function (e) { parent.events.push( ( e.target == body ) ? 'doc1.body.ondrag': 'doc1.bubble.ondrag' ); };
+ body.ondragenter = function (e) { parent.events.push( ( e.target == body ) ? 'doc1.body.ondragenter': 'doc1.bubble.ondragenter' ); };
+ body.ondragover = function (e) { parent.events.push( ( e.target == body ) ? 'doc1.body.ondragover': 'doc1.bubble.ondragover' ); };
+ body.ondrop = function (e) { parent.events.push( ( e.target == body ) ? 'doc1.body.ondrop': 'doc1.bubble.ondrop' ); };
+ body.ondragend = function (e) { parent.events.push( ( e.target == body ) ? 'doc1.body.ondragend': 'doc1.bubble.ondragend' ); };
+ body.onmousedown = function (e) { parent.events.push( ( e.target == body ) ? 'doc1.body.onmousedown': 'doc1.bubble.onmousedown' ); };
+ body.onmouseup = function (e) { parent.events.push( ( e.target == body ) ? 'doc1.body.onmouseup': 'doc1.bubble.onmouseup' ); };
+
+ function finish(e) {
+ var i, evindex;
+ var events = parent.events.join('-');
+ /*
+ Normalise; reduce repeating event sequences to only 2 occurrences.
+ This makes the final event sequence predictable, no matter how many times the drag->dragover sequences repeat.
+ Two occurrances are kept in each case to allow testing to make sure the sequence really is repeating.
+ */
+ //spec compliant - div dragenter is not cancelled, so body dragenter fires and body becomes current target
+ //repeats while drag is over orange or fuchsia or the body
+ events = events.replace(/(-doc1\.orange\.ondrag-doc1\.bubble\.ondrag-doc1\.body\.ondragover){3,}/g,'$1$1');
+ events = events.replace(/(-doc1\.orange\.ondrag-doc1\.bubble\.ondrag-doc2\.body\.ondragover){3,}/g,'$1$1');
+ //repeats while dragging over yellow
+ events = events.replace(/(-doc1\.orange\.ondrag-doc1\.bubble\.ondrag-doc2\.yellow\.ondragover-doc2\.bubble\.ondragover){3,}/g,'$1$1');
+ //repeats while dragging over blue
+ events = events.replace(/(-doc1\.orange\.ondrag-doc1\.bubble\.ondrag-doc2\.blue\.ondragover-doc2\.bubble\.ondragover){3,}/g,'$1$1');
+ //non-spec-compliant repeats while dragging over orange
+ events = events.replace(/(-doc1\.orange\.ondrag-doc1\.bubble\.ondrag-doc1\.orange\.ondragover-doc1\.bubble\.ondragover){3,}/g,'$1$1');
+ //non-spec-compliant repeats while dragging over fuchsia
+ events = events.replace(/(-doc1\.orange\.ondrag-doc1\.bubble\.ondrag-doc1\.pink\.ondragover-doc1\.bubble\.ondragover){3,}/g,'$1$1');
+ events = events.split(/-/g);
+
+ parent.test(function () {
+ parent.assert_array_equals(events,
+
+ ['doc1.orange.onmousedown', //mouse down
+ 'doc1.bubble.onmousedown',
+
+ 'doc1.orange.ondragstart', //dragging begins
+ 'doc1.bubble.ondragstart',
+
+ 'doc1.orange.ondrag', //mouse is over orange
+ 'doc1.bubble.ondrag',
+ 'doc1.orange.ondragenter', //not cancelled
+ 'doc1.bubble.ondragenter',
+ 'doc1.body.ondragenter', //so body becomes current target, and the event fires there as well
+ 'doc1.body.ondragover',
+
+ 'doc1.orange.ondrag', //start repeating (some over orange, some over body)
+ 'doc1.bubble.ondrag',
+ 'doc1.body.ondragover',
+ 'doc1.orange.ondrag', //...twice to make sure it actually repeats
+ 'doc1.bubble.ondrag',
+ 'doc1.body.ondragover', //end repeating
+
+ 'doc1.orange.ondrag', //mouse moves over pink
+ 'doc1.bubble.ondrag',
+ 'doc1.pink.ondragenter', //not cancelled
+ 'doc1.bubble.ondragenter',
+ 'doc1.body.ondragover', //so body becomes current target, but since it was already the target, dragenter does not need to fire again
+
+ 'doc1.orange.ondrag', //start repeating (some over pink, some over body)
+ 'doc1.bubble.ondrag',
+ 'doc1.body.ondragover',
+ 'doc1.orange.ondrag', //...twice to make sure it actually repeats
+ 'doc1.bubble.ondrag',
+ 'doc1.body.ondragover', //end repeating
+
+ 'doc1.orange.ondrag', //mouse moves over second frame
+ 'doc1.bubble.ondrag',
+ 'doc2.body.ondragenter', //not cancelled
+ 'doc2.body.ondragenter', //so it fires again and sets body as current target
+ 'doc2.body.ondragover',
+
+ 'doc1.orange.ondrag', //start repeating (over second body)
+ 'doc1.bubble.ondrag',
+ 'doc2.body.ondragover',
+ 'doc1.orange.ondrag', //...twice to make sure it actually repeats
+ 'doc1.bubble.ondrag',
+ 'doc2.body.ondragover', //end repeating
+
+ 'doc1.orange.ondrag', //mouse moves over yellow
+ 'doc1.bubble.ondrag',
+ 'doc2.yellow.ondragenter',
+ 'doc2.bubble.ondragenter',
+ 'doc2.yellow.ondragover',
+ 'doc2.bubble.ondragover',
+
+ 'doc1.orange.ondrag', //start repeating (over yellow)
+ 'doc1.bubble.ondrag',
+ 'doc2.yellow.ondragover',
+ 'doc2.bubble.ondragover',
+ 'doc1.orange.ondrag', //...twice to make sure it actually repeats
+ 'doc1.bubble.ondrag',
+ 'doc2.yellow.ondragover',
+ 'doc2.bubble.ondragover', //end repeating
+
+ 'doc1.orange.ondrag', //mouse moves over body
+ 'doc1.bubble.ondrag',
+ 'doc2.body.ondragenter', //not cancelled
+ 'doc2.body.ondragenter', //so it fires again and sets body as current target
+ 'doc2.body.ondragover',
+
+ 'doc1.orange.ondrag', //start repeating (over body)
+ 'doc1.bubble.ondrag',
+ 'doc2.body.ondragover',
+ 'doc1.orange.ondrag', //...twice to make sure it actually repeats
+ 'doc1.bubble.ondrag',
+ 'doc2.body.ondragover', //end repeating
+
+ 'doc1.orange.ondrag', //mouse moves over blue
+ 'doc1.bubble.ondrag',
+ 'doc2.blue.ondragenter',
+ 'doc2.bubble.ondragenter',
+ 'doc2.blue.ondragover',
+ 'doc2.bubble.ondragover',
+
+ 'doc1.orange.ondrag', //start repeating (over blue)
+ 'doc1.bubble.ondrag',
+ 'doc2.blue.ondragover',
+ 'doc2.bubble.ondragover',
+ 'doc1.orange.ondrag', //...twice to make sure it actually repeats
+ 'doc1.bubble.ondrag',
+ 'doc2.blue.ondragover',
+ 'doc2.bubble.ondragover', //end repeating
+
+ 'doc2.blue.ondrop', //release
+ 'doc2.bubble.ondrop',
+ 'doc1.orange.ondragend',
+ 'doc1.bubble.ondragend']
+
+ );
+ }, 'Overall sequence');
+ var div = parent.document.createElement("div");
+ div.setAttribute("id", "log");
+ parent.document.documentElement.appendChild(div);
+ parent.done();
+ document.body.appendChild(parent.document.querySelector("div"));
+ }
+};
+</script>
+
+<div id="testhere">
+<div draggable='true' id='orange'></div>
+<div id='fuchsia'></div>
+</div>
+
+<p>If you have already clicked on this page, reload it.</p>
+<p>Use your pointing device to slowly drag the orange square over the pink square, then the grey square, then the yellow square, then the blue square, and release it over the blue square (make sure the mouse remains over each square for at least 1 second, and over the gaps between squares for at least 1 second). Fail if no new text appears below.</p>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/events-cross-document-suite-HELPER-2.html b/testing/web-platform/tests/html/editing/dnd/events/events-cross-document-suite-HELPER-2.html
new file mode 100644
index 0000000000..343fc09543
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/events-cross-document-suite-HELPER-2.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<title>drag &amp; drop - event sequence for cross-document drag</title>
+<style type="text/css">
+ /* use margins instead of padding to make sure the body begins at the top of the page */
+ html, body {
+ margin: 0;
+ padding: 0;
+ height: 100%;
+ }
+ #testhere div {
+ height: 100px;
+ width: 100px;
+ position: absolute;
+ top: 8px;
+ }
+ body::before {
+ height: 100px;
+ width: 100px;
+ position: absolute;
+ top: 8px;
+ left: 0px;
+ content: "";
+ background-color: silver;
+ }
+ #yellow {
+ background-color: yellow;
+ left: 150px;
+ }
+ #blue {
+ background-color: navy;
+ left: 300px;
+ }
+</style>
+
+<script>
+window.onload = function () {
+ var yellow = document.querySelector('#yellow')
+ var blue = document.querySelector('#blue')
+ var body = document.body;
+
+ /* Events for the fuchsia box */
+ yellow.ondragstart = function () { parent.events.push('doc2.yellow.ondragstart'); };
+ yellow.ondrag = function () { parent.events.push('doc2.yellow.ondrag'); };
+ yellow.ondragenter = function () { parent.events.push('doc2.yellow.ondragenter'); return false; };
+ yellow.ondragover = function () { parent.events.push('doc2.yellow.ondragover'); return false; };
+ yellow.ondrop = function () { parent.events.push('doc2.yellow.ondrop'); return false; };
+ yellow.ondragend = function () { parent.events.push('doc2.yellow.ondragend'); };
+ yellow.onmousedown = function () { parent.events.push('doc2.yellow.onmousedown'); };
+ yellow.onmouseup = function () { parent.events.push('doc2.yellow.onmouseup'); };
+
+ /* Events for the blue box (droppable) */
+ blue.ondragstart = function () { parent.events.push('doc2.blue.ondragstart'); };
+ blue.ondrag = function () { parent.events.push('doc2.blue.ondrag'); };
+ blue.ondragenter = function () { parent.events.push('doc2.blue.ondragenter'); return false; };
+ blue.ondragover = function () { parent.events.push('doc2.blue.ondragover'); return false; };
+ blue.ondrop = function () { parent.events.push('doc2.blue.ondrop'); return false; };
+ blue.ondragend = function () { parent.events.push('doc2.blue.ondragend'); };
+ blue.onmousedown = function () { parent.events.push('doc2.blue.onmousedown'); };
+ blue.onmouseup = function () { parent.events.push('doc2.blue.onmouseup'); };
+
+ /* Events for the page body */
+ body.ondragstart = function (e) { parent.events.push( ( e.target == body ) ? 'doc2.body.ondragstart': 'doc2.bubble.ondragstart' ); };
+ body.ondrag = function (e) { parent.events.push( ( e.target == body ) ? 'doc2.body.ondrag': 'doc2.bubble.ondrag' ); };
+ body.ondragenter = function (e) { parent.events.push( ( e.target == body ) ? 'doc2.body.ondragenter': 'doc2.bubble.ondragenter' ); };
+ body.ondragover = function (e) { parent.events.push( ( e.target == body ) ? 'doc2.body.ondragover': 'doc2.bubble.ondragover' ); };
+ body.ondrop = function (e) { parent.events.push( ( e.target == body ) ? 'doc2.body.ondrop': 'doc2.bubble.ondrop' ); };
+ body.ondragend = function (e) { parent.events.push( ( e.target == body ) ? 'doc2.body.ondragend': 'doc2.bubble.ondragend' ); };
+ body.onmousedown = function (e) { parent.events.push( ( e.target == body ) ? 'doc2.body.onmousedown': 'doc2.bubble.onmousedown' ); };
+ body.onmouseup = function (e) { parent.events.push( ( e.target == body ) ? 'doc2.body.onmouseup': 'doc2.bubble.onmouseup' ); };
+
+};
+</script>
+
+<div id="testhere">
+<div id='yellow'></div>
+<div id='blue'></div>
+</div>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/events-cross-document-suite-manual.html b/testing/web-platform/tests/html/editing/dnd/events/events-cross-document-suite-manual.html
new file mode 100644
index 0000000000..9428a87760
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/events-cross-document-suite-manual.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>drag &amp; drop - event sequence for cross-document drag</title>
+<script type="text/javascript" src="/resources/testharness.js"></script>
+<script type="text/javascript" src="/resources/testharnessreport.js"></script>
+<script>
+var events = new Array();
+</script>
+
+<frameset cols="308,*" frameborder="no" border="0">
+ <frame src="events-cross-document-suite-HELPER-1.html">
+ <frame src="events-cross-document-suite-HELPER-2.html">
+</frameset>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/events-file-suite-manual.html b/testing/web-platform/tests/html/editing/dnd/events/events-file-suite-manual.html
new file mode 100644
index 0000000000..22a66f5e9a
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/events-file-suite-manual.html
@@ -0,0 +1,176 @@
+<!DOCTYPE html>
+<title>drag &amp; drop - event sequence for file drops</title>
+<script type="text/javascript" src="/resources/testharness.js"></script>
+<script type="text/javascript" src="/resources/testharnessreport.js"></script>
+<style type="text/css">
+ /* use margins instead of padding to make sure the body begins at the top of the page */
+ html, body {
+ margin: 0;
+ }
+ body {
+ padding: 116px 8px 8px;
+ }
+ body::before {
+ height: 108px;
+ width: 108px;
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ content: "";
+ background-color: orange;
+ }
+ #testhere div {
+ height: 100px;
+ width: 100px;
+ position: absolute;
+ top: 8px;
+ }
+ #fuchsia {
+ background-color: fuchsia;
+ left: 158px;
+ }
+ #yellow {
+ background-color: yellow;
+ left: 308px;
+ }
+ #blue {
+ background-color: navy;
+ left: 458px;
+ }
+</style>
+
+<script>
+setup(function () {},{explicit_done:true,explicit_timeout:true});
+window.onload = function () {
+ var fuchsia = document.querySelector('#fuchsia')
+ var yellow = document.querySelector('#yellow')
+ var blue = document.querySelector('#blue')
+ var body = document.body;
+
+ var events = new Array
+
+ /* Events for the fuchsia box */
+ fuchsia.ondragstart = function () { events.push('pink.ondragstart'); };
+ fuchsia.ondrag = function () { events.push('pink.ondrag'); };
+ fuchsia.ondragenter = function () { events.push('pink.ondragenter'); };
+ fuchsia.ondragover = function () { events.push('pink.ondragover'); };
+ fuchsia.ondragleave = function () { events.push('pink.ondragleave'); };
+ fuchsia.ondrop = function () { events.push('pink.ondrop'); return false; };
+ fuchsia.ondragend = function () { events.push('pink.ondragend'); };
+ fuchsia.onmousedown = function () { events.push('pink.onmousedown'); };
+ fuchsia.onmouseup = function () { events.push('pink.onmouseup'); };
+
+ /* Events for the fuchsia box */
+ yellow.ondragstart = function () { events.push('yellow.ondragstart'); };
+ yellow.ondrag = function () { events.push('yellow.ondrag'); };
+ yellow.ondragenter = function () { events.push('yellow.ondragenter'); return false; };
+ yellow.ondragover = function () { events.push('yellow.ondragover'); return false; };
+ yellow.ondragleave = function () { events.push('yellow.ondragleave'); };
+ yellow.ondrop = function () { events.push('yellow.ondrop'); return false; };
+ yellow.ondragend = function () { events.push('yellow.ondragend'); };
+ yellow.onmousedown = function () { events.push('yellow.onmousedown'); };
+ yellow.onmouseup = function () { events.push('yellow.onmouseup'); };
+
+ /* Events for the blue box (droppable) */
+ blue.ondragstart = function () { events.push('blue.ondragstart'); };
+ blue.ondrag = function () { events.push('blue.ondrag'); };
+ blue.ondragenter = function () { events.push('blue.ondragenter'); return false; };
+ blue.ondragover = function () { events.push('blue.ondragover'); return false; };
+ blue.ondragleave = function () { events.push('blue.ondragleave'); };
+ blue.ondrop = function () { events.push('blue.ondrop'); return false; };
+ blue.ondragend = function () { events.push('blue.ondragend'); };
+ blue.onmousedown = function () { events.push('blue.onmousedown'); };
+ blue.onmouseup = function () { events.push('blue.onmouseup'); };
+
+ /* Events for the page body */
+ body.ondragstart = function (e) { events.push( ( e.target == body ) ? 'body.ondragstart': 'bubble.ondragstart' ); };
+ body.ondrag = function (e) { events.push( ( e.target == body ) ? 'body.ondrag': 'bubble.ondrag' ); };
+ body.ondragenter = function (e) { events.push( ( e.target == body ) ? 'body.ondragenter': 'bubble.ondragenter' ); };
+ body.ondragover = function (e) { events.push( ( e.target == body ) ? 'body.ondragover': 'bubble.ondragover' ); };
+ body.ondragleave = function (e) { events.push( ( e.target == body ) ? 'body.ondragleave': 'bubble.ondragleave' ); };
+ body.ondrop = function (e) { events.push( ( e.target == body ) ? 'body.ondrop': 'bubble.ondrop' ); setTimeout(finish,200); };
+ body.ondragend = function (e) { events.push( ( e.target == body ) ? 'body.ondragend': 'bubble.ondragend' ); };
+ body.onmousedown = function (e) { events.push( ( e.target == body ) ? 'body.onmousedown': 'bubble.onmousedown' ); };
+ body.onmouseup = function (e) { events.push( ( e.target == body ) ? 'body.onmouseup': 'bubble.onmouseup' ); };
+
+ function finish(e) {
+ var i, evindex;
+ events = events.join('-');
+ /*
+ Normalise; reduce repeating event sequences to only 2 occurrences.
+ This makes the final event sequence predictable, no matter how many times the drag->dragover sequences repeat.
+ Two occurrances are kept in each case to allow testing to make sure the sequence really is repeating.
+ */
+ //spec compliant - div dragenter is not cancelled, so body dragenter fires and body becomes current target
+ //repeats while drag is over fuchsia or the body
+ events = events.replace(/(-body\.ondragover){3,}/g,'$1$1');
+ //repeats while dragging over yellow
+ events = events.replace(/(-yellow\.ondragover-bubble\.ondragover){3,}/g,'$1$1');
+ //repeats while dragging over blue
+ events = events.replace(/(-blue\.ondragover-bubble\.ondragover){3,}/g,'$1$1');
+ //non-spec-compliant repeats while dragging over fuchsia
+ events = events.replace(/(-pink\.ondragover-bubble\.ondragover){3,}/g,'$1$1');
+ events = events.split(/-/g);
+
+ test(function () {
+ assert_array_equals(events,
+
+ [/* 1 */ 'body.ondragenter', //mouse moves over body, which does not cancel event
+ /* 2 */ 'body.ondragenter', //so it fires again and sets body as current target
+
+ /* 3 */ 'body.ondragover', //start repeating over body
+ /* 4 */ 'body.ondragover', //...twice to make sure it actually repeats
+
+ /* 5 */ 'pink.ondragenter', //mouse moves over pink - not cancelled
+ /* 6 */ 'bubble.ondragenter',
+
+ /* 7 */ 'body.ondragover', //so body becomes current target, but since it was already the target, dragenter does not need to fire again
+ /* 8 */ 'body.ondragover', //...twice to make sure it actually repeats
+
+ /* 9 */ 'yellow.ondragenter', //mouse moves over yellow
+ /* 10 */ 'bubble.ondragenter',
+ /* 11 */ 'body.ondragleave',
+
+ /* 12 */ 'yellow.ondragover', //start repeating (over yellow)
+ /* 13 */ 'bubble.ondragover',
+ /* 14 */ 'yellow.ondragover', //...twice to make sure it actually repeats
+ /* 15 */ 'bubble.ondragover', //end repeating
+
+ /* 16 */ 'body.ondragenter', //mouse moves over body, not cancelled
+ /* 17 */ 'body.ondragenter', //so it fires again and sets body as current target
+ /* 18 */ 'yellow.ondragleave',
+ /* 19 */ 'bubble.ondragleave',
+
+ /* 20 */ 'body.ondragover', //start repeating (over body)
+ /* 21 */ 'body.ondragover', //...twice to make sure it actually repeats
+
+ /* 22 */ 'blue.ondragenter', //mouse moves over blue
+ /* 23 */ 'bubble.ondragenter',
+ /* 24 */ 'body.ondragleave',
+
+ /* 25 */ 'blue.ondragover', //start repeating (over blue)
+ /* 26 */ 'bubble.ondragover',
+ /* 27 */ 'blue.ondragover', //...twice to make sure it actually repeats
+ /* 28 */ 'bubble.ondragover',
+
+ /* 29 */ 'blue.ondrop', //release
+ /* 30 */ 'bubble.ondrop']
+
+ );
+ }, 'Overall sequence');
+
+ done();
+ }
+};
+</script>
+
+<div id="testhere">
+<div id='fuchsia'></div>
+<div id='yellow'></div>
+<div id='blue'></div>
+</div>
+
+<p>If you have already clicked on this page, reload it.</p>
+<p>Use your pointing device to slowly drag a file from your system's file manager, over the orange square (ensure that this is the first part of the page that you drag the file over, not an otherwise blank part of the page), then the pink square, then the yellow square, then the blue square, and release it over the blue square (make sure the mouse remains over each square for at least 1 second, and over the gaps between squares for at least 1 second). If a prompt appears, accept it. Fail if no new text appears below.</p>
+
+<div id="log"></div>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/events-non-draggable-001-manual.html b/testing/web-platform/tests/html/editing/dnd/events/events-non-draggable-001-manual.html
new file mode 100644
index 0000000000..0315ccdc86
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/events-non-draggable-001-manual.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<meta charset='utf-8'>
+<title>drag &amp; drop – events should not fire with non-draggable elements – 001</title>
+<style type="text/css">
+ div {
+ height: 200px;
+ width: 200px;
+ background-color: orange;
+ position: absolute;
+ top: 8px;
+ left: 8px;
+ }
+ div + p {
+ margin-top: 220px;
+ }
+</style>
+
+<script>
+window.onload = function() {
+
+ var elem = document.getElementsByTagName('div')[0];
+ var pass = true;
+
+ function fail() {
+ pass = false;
+ }
+
+ elem.addEventListener('drag',fail,false);
+ elem.addEventListener('dragend',fail,false);
+ elem.addEventListener('dragenter',fail,false);
+ elem.addEventListener('dragleave',fail,false);
+ elem.addEventListener('dragover',fail,false);
+ elem.addEventListener('dragstart',fail,false);
+ elem.addEventListener('drop',fail,false);
+
+ elem.ondrag = fail;
+ elem.ondragend = fail;
+ elem.ondragenter = fail;
+ elem.ondragleave = fail;
+ elem.ondragover = fail;
+ elem.ondragstart = fail;
+ elem.ondrop = fail;
+
+ elem.onmouseup = function () {
+ setTimeout(function () {
+ if (pass == true) {
+ document.body.innerHTML = 'PASS';
+ } else {
+ document.body.innerHTML = 'FAIL';
+ }
+ }, 100 );
+ };
+
+}
+</script>
+
+<div></div>
+
+<p>Click once on the orange box above, without moving the mouse while
+clicking. The word &quot;PASS&quot; should appear.</p>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/events-non-draggable-002-manual.html b/testing/web-platform/tests/html/editing/dnd/events/events-non-draggable-002-manual.html
new file mode 100644
index 0000000000..c890cb482e
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/events-non-draggable-002-manual.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+<meta charset='utf-8'>
+<title>drag &amp; drop – events should not fire with non-draggable elements – 002</title>
+<style type="text/css">
+ div {
+ height: 200px;
+ width: 200px;
+ background-color: orange;
+ position: absolute;
+ top: 8px;
+ left: 8px;
+ }
+ div + div {
+ background-color: navy;
+ left: 250px;
+ }
+
+ div + p {
+ margin-top: 220px;
+ }
+</style>
+
+<script>
+window.onload = function() {
+
+ var orange = document.getElementsByTagName('div')[0];
+ var blue = document.getElementsByTagName('div')[1];
+ var body = document.body;
+
+ var pass = true;
+
+ function fail() {
+ pass = false;
+ }
+
+ body.addEventListener('drag',fail,false);
+ body.addEventListener('dragend',fail,false);
+ body.addEventListener('dragenter',fail,false);
+ body.addEventListener('dragleave',fail,false);
+ body.addEventListener('dragover',fail,false);
+ body.addEventListener('dragstart',fail,false);
+ body.addEventListener('drop',fail,false);
+
+ body.ondrag = fail;
+ body.ondragend = fail;
+ body.ondragenter = fail;
+ body.ondragleave = fail;
+ body.ondragover = fail;
+ body.ondragstart = fail;
+ body.ondrop = fail;
+
+ orange.addEventListener('drag',fail,false);
+ orange.addEventListener('dragend',fail,false);
+ orange.addEventListener('dragenter',fail,false);
+ orange.addEventListener('dragleave',fail,false);
+ orange.addEventListener('dragover',fail,false);
+ orange.addEventListener('dragstart',fail,false);
+ orange.addEventListener('drop',fail,false);
+
+ orange.ondrag = fail;
+ orange.ondragend = fail;
+ orange.ondragenter = fail;
+ orange.ondragleave = fail;
+ orange.ondragover = fail;
+ orange.ondragstart = fail;
+ orange.ondrop = fail;
+
+ blue.addEventListener('drag',fail,false);
+ blue.addEventListener('dragend',fail,false);
+ blue.addEventListener('dragenter',fail,false);
+ blue.addEventListener('dragleave',fail,false);
+ blue.addEventListener('dragover',fail,false);
+ blue.addEventListener('dragstart',fail,false);
+ blue.addEventListener('drop',fail,false);
+
+ blue.ondrag = fail;
+ blue.ondragend = fail;
+ blue.ondragenter = fail;
+ blue.ondragleave = fail;
+ blue.ondragover = fail;
+ blue.ondragstart = fail;
+ blue.ondrop = fail;
+
+ body.onmouseup = function () {
+ setTimeout(function () {
+ if (pass == true) {
+ document.body.innerHTML = 'PASS';
+ } else {
+ document.body.innerHTML = 'FAIL';
+ }
+ }, 100 );
+ };
+
+}
+</script>
+
+<div></div>
+<div></div>
+
+<p>Use your pointing device to drag from the orange box to the blue box. The
+word &quot;PASS&quot; should appear.
diff --git a/testing/web-platform/tests/html/editing/dnd/events/events-suite-manual.html b/testing/web-platform/tests/html/editing/dnd/events/events-suite-manual.html
new file mode 100644
index 0000000000..16c6583dc8
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/events-suite-manual.html
@@ -0,0 +1,371 @@
+<!DOCTYPE html>
+<title>drag &amp; drop - event sequence for draggable elements</title>
+<script type="text/javascript" src="/resources/testharness.js"></script>
+<script type="text/javascript" src="/resources/testharnessreport.js"></script>
+<style type="text/css">
+ /* use margins instead of padding to make sure the body begins at the top of the page */
+ html, body {
+ margin: 0;
+ }
+ body {
+ padding: 116px 8px 8px;
+ }
+ #testhere div {
+ height: 100px;
+ width: 100px;
+ position: absolute;
+ top: 8px;
+ }
+ #orange {
+ background-color: orange;
+ left: 8px;
+ }
+ #fuchsia {
+ background-color: fuchsia;
+ left: 158px;
+ }
+ #yellow {
+ background-color: yellow;
+ left: 308px;
+ }
+ #blue {
+ background-color: navy;
+ left: 458px;
+ }
+</style>
+
+<script>
+setup(function () {},{explicit_done:true,explicit_timeout:true});
+window.onload = function () {
+ var orange = document.querySelector('#orange')
+ var fuchsia = document.querySelector('#fuchsia')
+ var yellow = document.querySelector('#yellow')
+ var blue = document.querySelector('#blue')
+ var body = document.body;
+
+ var events = new Array
+
+ orange.ondragstart = function (e) {
+ events.push('orange.ondragstart');
+ e.dataTransfer.effectAllowed = 'copy';
+ e.dataTransfer.setData('Text', 'foo');
+ };
+ orange.ondrag = function () { events.push('orange.ondrag'); };
+ orange.ondragenter = function () { events.push('orange.ondragenter'); };
+ orange.ondragover = function () { events.push('orange.ondragover'); };
+ orange.ondragleave = function () { events.push('orange.ondragleave'); };
+ orange.ondrop = function () { events.push('orange.ondrop'); return false; };
+ orange.ondragend = function () { events.push('orange.ondragend'); };
+ orange.onmousedown = function () { events.push('orange.onmousedown'); };
+ orange.onmouseup = function () { events.push('orange.onmouseup'); };
+
+ /* Events for the fuchsia box */
+ fuchsia.ondragstart = function () { events.push('pink.ondragstart'); };
+ fuchsia.ondrag = function () { events.push('pink.ondrag'); };
+ fuchsia.ondragenter = function () { events.push('pink.ondragenter'); };
+ fuchsia.ondragover = function () { events.push('pink.ondragover'); };
+ fuchsia.ondragleave = function () { events.push('pink.ondragleave'); };
+ fuchsia.ondrop = function () { events.push('pink.ondrop'); return false; };
+ fuchsia.ondragend = function () { events.push('pink.ondragend'); };
+ fuchsia.onmousedown = function () { events.push('pink.onmousedown'); };
+ fuchsia.onmouseup = function () { events.push('pink.onmouseup'); };
+
+ /* Events for the fuchsia box */
+ yellow.ondragstart = function () { events.push('yellow.ondragstart'); };
+ yellow.ondrag = function () { events.push('yellow.ondrag'); };
+ yellow.ondragenter = function () { events.push('yellow.ondragenter'); return false; };
+ yellow.ondragover = function () { events.push('yellow.ondragover'); return false; };
+ yellow.ondragleave = function () { events.push('yellow.ondragleave'); };
+ yellow.ondrop = function () { events.push('yellow.ondrop'); return false; };
+ yellow.ondragend = function () { events.push('yellow.ondragend'); };
+ yellow.onmousedown = function () { events.push('yellow.onmousedown'); };
+ yellow.onmouseup = function () { events.push('yellow.onmouseup'); };
+
+ /* Events for the blue box (droppable) */
+ blue.ondragstart = function () { events.push('blue.ondragstart'); };
+ blue.ondrag = function () { events.push('blue.ondrag'); };
+ blue.ondragenter = function () { events.push('blue.ondragenter'); return false; };
+ blue.ondragover = function () { events.push('blue.ondragover'); return false; };
+ blue.ondragleave = function () { events.push('blue.ondragleave'); };
+ blue.ondrop = function () { events.push('blue.ondrop'); return false; };
+ blue.ondragend = function () { events.push('blue.ondragend'); };
+ blue.onmousedown = function () { events.push('blue.onmousedown'); };
+ blue.onmouseup = function () { events.push('blue.onmouseup'); };
+
+ /* Events for the page body */
+ body.ondragstart = function (e) { events.push( ( e.target == body ) ? 'body.ondragstart': 'bubble.ondragstart' ); };
+ body.ondrag = function (e) { events.push( ( e.target == body ) ? 'body.ondrag': 'bubble.ondrag' ); };
+ body.ondragenter = function (e) { events.push( ( e.target == body ) ? 'body.ondragenter': 'bubble.ondragenter' ); };
+ body.ondragover = function (e) { events.push( ( e.target == body ) ? 'body.ondragover': 'bubble.ondragover' ); };
+ body.ondragleave = function (e) { events.push( ( e.target == body ) ? 'body.ondragleave': 'bubble.ondragleave' ); };
+ body.ondrop = function (e) { events.push( ( e.target == body ) ? 'body.ondrop': 'bubble.ondrop' ); };
+ body.ondragend = function (e) { events.push( ( e.target == body ) ? 'body.ondragend': 'bubble.ondragend' ); setTimeout(finish,100); };
+ body.onmousedown = function (e) { events.push( ( e.target == body ) ? 'body.onmousedown': 'bubble.onmousedown' ); };
+ body.onmouseup = function (e) { events.push( ( e.target == body ) ? 'body.onmouseup': 'bubble.onmouseup' ); };
+
+ function finish(e) {
+ var i, evindex;
+ events = events.join('-');
+ /*
+ Normalise; reduce repeating event sequences to only 2 occurrences.
+ This makes the final event sequence predictable, no matter how many times the drag->dragover sequences repeat.
+ Two occurrances are kept in each case to allow testing to make sure the sequence really is repeating.
+ */
+ //spec compliant - div dragenter is not cancelled, so body dragenter fires and body becomes current target
+ //repeats while drag is over orange or fuchsia or the body
+ events = events.replace(/(-orange\.ondrag-bubble\.ondrag-body\.ondragover){3,}/g,'$1$1');
+ //repeats while dragging over yellow
+ events = events.replace(/(-orange\.ondrag-bubble\.ondrag-yellow\.ondragover-bubble\.ondragover){3,}/g,'$1$1');
+ //repeats while dragging over blue
+ events = events.replace(/(-orange\.ondrag-bubble\.ondrag-blue\.ondragover-bubble\.ondragover){3,}/g,'$1$1');
+ //non-spec-compliant repeats while dragging over orange
+ events = events.replace(/(-orange\.ondrag-bubble\.ondrag-orange\.ondragover-bubble\.ondragover){3,}/g,'$1$1');
+ //non-spec-compliant repeats while dragging over fuchsia
+ events = events.replace(/(-orange\.ondrag-bubble\.ondrag-pink\.ondragover-bubble\.ondragover){3,}/g,'$1$1');
+ events = events.split(/-/g);
+
+ test(function () {
+ assert_array_equals(events,
+
+ [/* 1 */ 'orange.onmousedown', //mouse down
+ /* 2 */ 'bubble.onmousedown',
+
+ /* 3 */ 'orange.ondragstart', //dragging begins
+ /* 4 */ 'bubble.ondragstart',
+
+ /* 5 */ 'orange.ondrag', //mouse is over orange
+ /* 6 */ 'bubble.ondrag',
+ /* 7 */ 'orange.ondragenter', //not cancelled
+ /* 8 */ 'bubble.ondragenter',
+ /* 9 */ 'body.ondragenter', //so body becomes current target, and the event fires there as well
+ /* 10 */ 'body.ondragover',
+
+ /* 11 */ 'orange.ondrag', //start repeating (some over orange, some over body)
+ /* 12 */ 'bubble.ondrag',
+ /* 13 */ 'body.ondragover',
+ /* 14 */ 'orange.ondrag', //...twice to make sure it actually repeats
+ /* 15 */ 'bubble.ondrag',
+ /* 16 */ 'body.ondragover', //end repeating
+
+ /* 17 */ 'orange.ondrag', //mouse moves over pink
+ /* 18 */ 'bubble.ondrag',
+ /* 19 */ 'pink.ondragenter', //not cancelled
+ /* 20 */ 'bubble.ondragenter',
+ /* 21 */ 'body.ondragover', //so body becomes current target, but since it was already the target, dragenter does not need to fire again
+
+ /* 22 */ 'orange.ondrag', //start repeating (some over pink, some over body)
+ /* 23 */ 'bubble.ondrag',
+ /* 24 */ 'body.ondragover',
+ /* 25 */ 'orange.ondrag', //...twice to make sure it actually repeats
+ /* 26 */ 'bubble.ondrag',
+ /* 27 */ 'body.ondragover', //end repeating
+
+ /* 28 */ 'orange.ondrag', //mouse moves over yellow
+ /* 29 */ 'bubble.ondrag',
+ /* 30 */ 'yellow.ondragenter',
+ /* 31 */ 'bubble.ondragenter',
+ /* 32 */ 'body.ondragleave',
+ /* 33 */ 'yellow.ondragover',
+ /* 34 */ 'bubble.ondragover',
+
+ /* 35 */ 'orange.ondrag', //start repeating (over yellow)
+ /* 36 */ 'bubble.ondrag',
+ /* 37 */ 'yellow.ondragover',
+ /* 38 */ 'bubble.ondragover',
+ /* 39 */ 'orange.ondrag', //...twice to make sure it actually repeats
+ /* 40 */ 'bubble.ondrag',
+ /* 41 */ 'yellow.ondragover',
+ /* 42 */ 'bubble.ondragover', //end repeating
+
+ /* 43 */ 'orange.ondrag', //mouse moves over body
+ /* 44 */ 'bubble.ondrag',
+ /* 45 */ 'body.ondragenter', //not cancelled
+ /* 46 */ 'body.ondragenter', //so it fires again and sets body as current target
+ /* 47 */ 'yellow.ondragleave',
+ /* 48 */ 'bubble.ondragleave',
+ /* 49 */ 'body.ondragover',
+
+ /* 50 */ 'orange.ondrag', //start repeating (over body)
+ /* 51 */ 'bubble.ondrag',
+ /* 52 */ 'body.ondragover',
+ /* 53 */ 'orange.ondrag', //...twice to make sure it actually repeats
+ /* 54 */ 'bubble.ondrag',
+ /* 55 */ 'body.ondragover', //end repeating
+
+ /* 56 */ 'orange.ondrag', //mouse moves over blue
+ /* 57 */ 'bubble.ondrag',
+ /* 58 */ 'blue.ondragenter',
+ /* 59 */ 'bubble.ondragenter',
+ /* 60 */ 'body.ondragleave',
+ /* 61 */ 'blue.ondragover',
+ /* 62 */ 'bubble.ondragover',
+
+ /* 63 */ 'orange.ondrag', //start repeating (over blue)
+ /* 64 */ 'bubble.ondrag',
+ /* 65 */ 'blue.ondragover',
+ /* 66 */ 'bubble.ondragover',
+ /* 67 */ 'orange.ondrag', //...twice to make sure it actually repeats
+ /* 68 */ 'bubble.ondrag',
+ /* 69 */ 'blue.ondragover',
+ /* 70 */ 'bubble.ondragover', //end repeating
+
+ /* 71 */ 'blue.ondrop', //release
+ /* 72 */ 'bubble.ondrop',
+ /* 73 */ 'orange.ondragend',
+ /* 74 */ 'bubble.ondragend']
+
+ );
+ }, 'Overall sequence');
+
+ /* ondragstart */
+ test(function () { assert_true( events.indexOf('orange.ondragstart') != -1 ); }, "orange.ondragstart should fire");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'orange.ondragstart') return e; }).length, 1); }, "orange.ondragstart should fire 1 time");
+ test(function () { assert_equals( events[2], 'orange.ondragstart' ); }, "orange.ondragstart should be event handler #3");
+ test(function () { assert_equals( events.indexOf('pink.ondragstart'), -1 ); }, "pink.ondragstart should not fire");
+ test(function () { assert_equals( events.indexOf('yellow.ondragstart'), -1 ); }, "yellow.ondragstart should not fire");
+ test(function () { assert_equals( events.indexOf('blue.ondragstart'), -1 ); }, "blue.ondragstart should not fire");
+ test(function () { assert_equals( events.indexOf('body.ondragstart'), -1 ); }, "ondragstart should not fire at the body");
+ test(function () { assert_true( events.indexOf('bubble.ondragstart') != -1 ); }, "ondragstart should bubble to body");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'bubble.ondragstart') return e; }).length, 1); }, "ondragstart should only bubble to body 1 time");
+ test(function () { assert_equals( events[3], 'bubble.ondragstart' ); }, "ondragstart should bubble to body as event handler #4");
+
+ /* ondrag */
+ test(function () { assert_true( events.indexOf('orange.ondrag') != -1 ); }, "orange.ondrag should fire");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'orange.ondrag') return e; }).length, 15); }, "orange.ondrag should fire 15 times");
+ for( var i = 0, evindex = [4,10,13,16,21,24,27,34,38,42,49,52,55,62,66]; i < evindex.length; i++ ) {
+ test(function () { assert_equals( events[evindex[i]], 'orange.ondrag' ); }, "orange.ondrag should be event handler #"+(evindex[i]+1));
+ }
+ test(function () { assert_equals( events.indexOf('pink.ondrag'), -1 ); }, "pink.ondrag should not fire");
+ test(function () { assert_equals( events.indexOf('yellow.ondrag'), -1 ); }, "yellow.ondrag should not fire");
+ test(function () { assert_equals( events.indexOf('blue.ondrag'), -1 ); }, "blue.ondrag should not fire");
+ test(function () { assert_equals( events.indexOf('body.ondrag'), -1 ); }, "ondrag should not fire at the body");
+ test(function () { assert_true( events.indexOf('bubble.ondrag') != -1 ); }, "ondrag should bubble to body");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'bubble.ondrag') return e; }).length, 15); }, "ondrag should bubble to body 15 times");
+ for( var i = 0, evindex = [5,11,14,17,22,25,28,35,39,43,50,53,56,63,67]; i < evindex.length; i++ ) {
+ test(function () { assert_equals( events[evindex[i]], 'bubble.ondrag' ); }, "ondrag should bubble to body as event handler #"+(evindex[i]+1));
+ }
+
+ /* ondragenter */
+ test(function () { assert_true( events.indexOf('orange.ondragenter') != -1 ); }, "orange.ondragenter should fire");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'orange.ondragenter') return e; }).length, 1); }, "orange.ondragenter should fire 1 time");
+ test(function () { assert_equals( events[6], 'orange.ondragenter' ); }, "orange.ondragenter should be event handler #7");
+ test(function () { assert_true( events.indexOf('pink.ondragenter') != -1 ); }, "pink.ondragenter should fire");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'pink.ondragenter') return e; }).length, 1); }, "pink.ondragenter should fire 1 time");
+ test(function () { assert_equals( events[18], 'pink.ondragenter' ); }, "pink.ondragenter should be event handler #19");
+ test(function () { assert_true( events.indexOf('yellow.ondragenter') != -1 ); }, "yellow.ondragenter should fire");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'yellow.ondragenter') return e; }).length, 1); }, "yellow.ondragenter should fire 1 time");
+ test(function () { assert_equals( events[29], 'yellow.ondragenter' ); }, "yellow.ondragenter should be event handler #30");
+ test(function () { assert_true( events.indexOf('blue.ondragenter') != -1 ); }, "blue.ondragenter should fire");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'blue.ondragenter') return e; }).length, 1); }, "blue.ondragenter should fire 1 time");
+ test(function () { assert_equals( events[57], 'blue.ondragenter' ); }, "blue.ondragenter should be event handler #58");
+ test(function () { assert_true( events.indexOf('body.ondragenter') != -1 ); }, "ondragenter should fire at body");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'body.ondragenter') return e; }).length, 3); }, "ondragenter should fire at body 2 times");
+ for( var i = 0, evindex = [8,44,45]; i < evindex.length; i++ ) {
+ test(function () { assert_equals( events[evindex[i]], 'body.ondragenter' ); }, "ondragenter should fire at body as event handler #"+(evindex[i]+1));
+ }
+ test(function () { assert_true( events.indexOf('bubble.ondragenter') != -1 ); }, "ondragenter should bubble to body");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'bubble.ondragenter') return e; }).length, 4); }, "ondragenter should bubble to body 4 times");
+ for( var i = 0, evindex = [7,19,30,58]; i < evindex.length; i++ ) {
+ test(function () { assert_equals( events[evindex[i]], 'bubble.ondragenter' ); }, "ondragenter should bubble to body as event handler #"+(evindex[i]+1));
+ }
+
+ /* ondragover */
+ test(function () { assert_equals( events.indexOf('orange.ondragover'), -1 ); }, "orange.ondragover should not fire");
+ test(function () { assert_equals( events.indexOf('pink.ondragover'), -1 ); }, "pink.ondragover should not fire");
+ test(function () { assert_true( events.indexOf('yellow.ondragover') != -1 ); }, "yellow.ondragover should fire");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'yellow.ondragover') return e; }).length, 3); }, "yellow.ondragover should fire 3 times");
+ for( var i = 0, evindex = [32,36,40]; i < evindex.length; i++ ) {
+ test(function () { assert_equals( events[evindex[i]], 'yellow.ondragover' ); }, "yellow.ondragover should be event handler #"+(evindex[i]+1));
+ }
+ test(function () { assert_true( events.indexOf('blue.ondragover') != -1 ); }, "blue.ondragover should fire");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'blue.ondragover') return e; }).length, 3); }, "blue.ondragover should fire 9 times");
+ for( var i = 0, evindex = [60,64,68]; i < evindex.length; i++ ) {
+ test(function () { assert_equals( events[evindex[i]], 'blue.ondragover' ); }, "blue.ondragover should be event handler #"+(evindex[i]+1));
+ }
+ test(function () { assert_true( events.indexOf('body.ondragover') != -1 ); }, "ondragover should fire at body");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'body.ondragover') return e; }).length, 9); }, "ondragover should fire at body 2 times");
+ for( var i = 0, evindex = [9,12,15,20,23,26,48,51,54]; i < evindex.length; i++ ) {
+ test(function () { assert_equals( events[evindex[i]], 'body.ondragover' ); }, "ondragover should fire at body as event handler #"+(evindex[i]+1));
+ }
+ test(function () { assert_true( events.indexOf('bubble.ondragover') != -1 ); }, "ondragover should bubble to body");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'bubble.ondragover') return e; }).length, 6); }, "ondragover should bubble to body 6 times");
+ for( var i = 0, evindex = [33,37,41,61,65,69]; i < evindex.length; i++ ) {
+ test(function () { assert_equals( events[evindex[i]], 'bubble.ondragover' ); }, "ondragover should bubble to body as event handler #"+(evindex[i]+1));
+ }
+
+ /* ondragleave */
+ test(function () { assert_equals( events.indexOf('orange.ondragleave'), -1 ); }, "orange.ondragleave should not fire");
+ test(function () { assert_equals( events.indexOf('pink.ondragleave'), -1 ); }, "pink.ondragleave should not fire");
+ test(function () { assert_true( events.indexOf('yellow.ondragleave') != -1 ); }, "yellow.ondragleave should fire");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'yellow.ondragleave') return e; }).length, 1); }, "yellow.ondragleave should fire 1 time");
+ test(function () { assert_equals( events[46], 'yellow.ondragleave' ); }, "yellow.ondragleave should be event handler #47");
+ test(function () { assert_equals( events.indexOf('blue.ondragleave'), -1 ); }, "blue.ondragleave should not fire");
+ test(function () { assert_true( events.indexOf('body.ondragleave') != -1 ); }, "ondragleave should fire at body");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'body.ondragleave') return e; }).length, 2); }, "ondragleave should fire at body 2 times");
+ for( var i = 0, evindex = [31,59]; i < evindex.length; i++ ) {
+ test(function () { assert_equals( events[evindex[i]], 'body.ondragleave' ); }, "ondragleave should fire at body as event handler #"+(evindex[i]+1));
+ }
+ test(function () { assert_true( events.indexOf('bubble.ondragleave') != -1 ); }, "ondragleave should bubble to body");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'bubble.ondragleave') return e; }).length, 1); }, "ondragleave should bubble to body 1 time");
+ test(function () { assert_equals( events[47], 'bubble.ondragleave' ); }, "ondragleave should bubble to body as event handler #48");
+
+ /* ondrop */
+ test(function () { assert_equals( events.indexOf('orange.ondrop'), -1 ); }, "orange.ondrop should not fire");
+ test(function () { assert_equals( events.indexOf('pink.ondrop'), -1 ); }, "pink.ondrop should not fire");
+ test(function () { assert_equals( events.indexOf('yellow.ondrop'), -1 ); }, "yellow.ondrop should not fire");
+ test(function () { assert_true( events.indexOf('blue.ondrop') != -1 ); }, "blue.ondrop should fire");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'blue.ondrop') return e; }).length, 1); }, "blue.ondrop should fire 1 time");
+ test(function () { assert_equals( events[70], 'blue.ondrop' ); }, "blue.ondrop should be event handler #71");
+ test(function () { assert_equals( events.indexOf('body.ondrop'), -1 ); }, "ondrop should not fire at body");
+ test(function () { assert_true( events.indexOf('bubble.ondrop') != -1 ); }, "ondrop should bubble to body");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'bubble.ondrop') return e; }).length, 1); }, "ondrop should bubble to body 1 time");
+ test(function () { assert_equals( events[71], 'bubble.ondrop' ); }, "ondrop should bubble to body as event handler #72");
+
+ /* ondragend */
+ test(function () { assert_true( events.indexOf('orange.ondragend') != -1 ); }, "orange.ondragend should fire");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'orange.ondragend') return e; }).length, 1); }, "orange.ondragend should fire 1 time");
+ test(function () { assert_equals( events[72], 'orange.ondragend' ); }, "orange.ondragend should be event handler #73");
+ test(function () { assert_equals( events.indexOf('pink.ondragend'), -1 ); }, "pink.ondragend should not fire");
+ test(function () { assert_equals( events.indexOf('yellow.ondragend'), -1 ); }, "yellow.ondragend should not fire");
+ test(function () { assert_equals( events.indexOf('blue.ondragend'), -1 ); }, "blue.ondragend should not fire");
+ test(function () { assert_equals( events.indexOf('body.ondragend'), -1 ); }, "ondragend should not fire at body");
+ test(function () { assert_true( events.indexOf('bubble.ondragend') != -1 ); }, "ondragend should bubble to body");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'bubble.ondragend') return e; }).length, 1); }, "ondragend should bubble to body 1 time");
+ test(function () { assert_equals( events[73], 'bubble.ondragend' ); }, "ondragend should bubble to body as event handler #74");
+
+ /* onmousedown */
+ test(function () { assert_true( events.indexOf('orange.onmousedown') != -1 ); }, "orange.onmousedown should fire");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'orange.onmousedown') return e; }).length, 1); }, "orange.onmousedown should fire 1 time");
+ test(function () { assert_equals( events[0], 'orange.onmousedown' ); }, "orange.onmousedown should be event handler #1");
+ test(function () { assert_equals( events.indexOf('pink.onmousedown'), -1 ); }, "pink.onmousedown should not fire");
+ test(function () { assert_equals( events.indexOf('yellow.onmousedown'), -1 ); }, "yellow.onmousedown should not fire");
+ test(function () { assert_equals( events.indexOf('blue.onmousedown'), -1 ); }, "blue.onmousedown should not fire");
+ test(function () { assert_equals( events.indexOf('body.onmousedown'), -1 ); }, "onmousedown should not fire at body");
+ test(function () { assert_true( events.indexOf('bubble.onmousedown') != -1 ); }, "onmousedown should bubble to body");
+ test(function () { assert_equals( events.filter(function (e) { if (e == 'bubble.onmousedown') return e; }).length, 1); }, "onmousedown should bubble to body 1 time");
+ test(function () { assert_equals( events[1], 'bubble.onmousedown' ); }, "onmousedown should bubble to body as event handler #1");
+
+ /* onmouseup */
+ test(function () { assert_equals( events.indexOf('orange.onmouseup'), -1 ); }, "orange.onmouseup should not fire");
+ test(function () { assert_equals( events.indexOf('pink.onmouseup'), -1 ); }, "pink.onmouseup should not fire");
+ test(function () { assert_equals( events.indexOf('yellow.onmouseup'), -1 ); }, "yellow.onmouseup should not fire");
+ test(function () { assert_equals( events.indexOf('blue.onmouseup'), -1 ); }, "blue.onmouseup should not fire");
+ test(function () { assert_equals( events.indexOf('body.onmouseup'), -1 ); }, "onmouseup should not fire at body");
+ test(function () { assert_equals( events.indexOf('bubble.onmouseup'), -1 ); }, "onmouseup should not bubble to body");
+
+ done();
+ }
+};
+</script>
+
+<div id="testhere">
+<div draggable='true' id='orange'></div>
+<div id='fuchsia'></div>
+<div id='yellow'></div>
+<div id='blue'></div>
+</div>
+
+<p>If you have already clicked on this page, reload it.</p>
+<p>Use your pointing device to slowly drag the orange square over the pink square then the yellow square, then the blue square, and release it over the blue square (make sure the mouse remains over each square for at least 1 second, and over the gaps between squares for at least 1 second). Fail if no new text appears below.</p>
+
+<div id="log"></div>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/helper-drag-me-input-with-circle.xhtml b/testing/web-platform/tests/html/editing/dnd/events/helper-drag-me-input-with-circle.xhtml
new file mode 100644
index 0000000000..966afe4400
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/helper-drag-me-input-with-circle.xhtml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Cross frame drag and drop: helper file</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function start(event)
+ {if(step++ == 1)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragstart should be first event to fire.')}
+ }
+function leavePage(event)
+ {if(step++ > 1)
+ {setColor('green green silver silver')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragleave should fire after dragstart.')}
+ }
+function endDrag(event)
+ {if(step++ > 2)
+ {setColor('green')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragend should fire after dragstart and dragleave.')}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body onload="document.querySelector('input').select()" ondragleave="leavePage(event)">
+<p ondragstart="start(event)" ondragend="endDrag(event)"><input value="Drag me"/></p>
+<p>Drag selected text out of frame and drop it somewhere on the page. Both circles should turn green once text is dropped.</p>
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/helper-drag-me-link-with-circle.xhtml b/testing/web-platform/tests/html/editing/dnd/events/helper-drag-me-link-with-circle.xhtml
new file mode 100644
index 0000000000..c85f228619
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/helper-drag-me-link-with-circle.xhtml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Cross frame drag and drop: helper file</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function start(event)
+ {if(step++ == 1)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragstart should be first event to fire.')}
+ }
+function leavePage(event)
+ {if(step++ > 1)
+ {setColor('green green silver silver')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragleave should fire after dragstart.')}
+ }
+function endDrag(event)
+ {if(step++ > 2)
+ {setColor('green')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragend should fire after dragstart and dragleave.')}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body ondragleave="leavePage(event)">
+<p><a href="data:text/plain,1" ondragstart="start(event)" ondragend="endDrag(event)">Drag me</a></p>
+<p>Drag link out of frame and drop it somewhere on the page. Both circles should turn green once link is dropped.</p>
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/helper-drag-me-p-with-circle.xhtml b/testing/web-platform/tests/html/editing/dnd/events/helper-drag-me-p-with-circle.xhtml
new file mode 100644
index 0000000000..efbd4b7614
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/helper-drag-me-p-with-circle.xhtml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Cross frame drag and drop: helper file</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function start(event)
+ {if(step++ == 1)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragstart should be first event to fire.')}
+ }
+function leavePage(event)
+ {if(step++ > 1)
+ {setColor('green green silver silver')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragleave should fire after dragstart.')}
+ }
+function endDrag(event)
+ {if(step++ > 2)
+ {setColor('green')}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragend should fire after dragstart and dragleave.')}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body onload="window.getSelection().selectAllChildren(document.querySelector('p'))" ondragleave="leavePage(event)">
+<p ondragstart="start(event)" ondragend="endDrag(event)">Drag me</p>
+<p>Drag selected text out of frame and drop it somewhere on the page. Both circles should turn green once text is dropped.</p>
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/helper-drop-here-body-circle.xhtml b/testing/web-platform/tests/html/editing/dnd/events/helper-drop-here-body-circle.xhtml
new file mode 100644
index 0000000000..bb8c0e36f0
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/helper-drop-here-body-circle.xhtml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Cross frame drag and drop: helper file</title>
+<style type="text/css">
+div
+ {width:0;
+ height:0;
+ border:solid 50px silver;
+ border-radius:50px;
+ margin-left:auto;}
+</style>
+<script type="application/ecmascript">
+var step = 1;
+function enterPage(event)
+ {event.preventDefault();
+ if(step++ > 0)
+ {setColor('green silver silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragenter should fire before dragover and drop');}
+ }
+function overPage(event)
+ {event.preventDefault();
+ if(step++ > 1)
+ {setColor('green green silver silver');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragover should fire after dragenter');}
+ }
+function dropIt(event)
+ {if(step++ > 1)
+ {setColor('green');}
+ else
+ {step = 0;
+ setColor('maroon');
+ say('Dragover should fire after dragenter');}
+ }
+function say(it)
+ {document.querySelector('pre').appendChild(document.createTextNode(it + '\n'))}
+function setColor(c)
+ {document.querySelector('div').setAttribute('style','border-color:' + c)}
+</script>
+</head>
+<body ondragenter="enterPage(event)" ondragover="overPage(event)" ondrop="dropIt(event)">
+<div/>
+<pre/>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/historical-manual.html b/testing/web-platform/tests/html/editing/dnd/events/historical-manual.html
new file mode 100644
index 0000000000..0e2147222d
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/historical-manual.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<title>Historical drag-and-drop features</title>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+.test-square {
+ width: 100px;
+ height: 100px;
+}
+
+#draggable {
+ background: orange;
+}
+
+#dropzone {
+ background: blue;
+}
+</style>
+
+<p>Drag the orange square onto the blue square and release it.</p>
+
+<div draggable="true" id="draggable" class="test-square" ondragstart="event.dataTransfer.setData('text/plain', null)"></div>
+<div id="dropzone" class="test-square"></div>
+
+<script>
+"use strict";
+
+async_test(t => {
+ let dragexitCount = 0;
+ document.addEventListener("dragexit", () => {
+ ++dragexitCount;
+ });
+
+ // Prevent the event to allow drop
+ document.addEventListener("dragover", e => {
+ e.preventDefault();
+ });
+
+ document.addEventListener("drop", t.step_func_done(() => {
+ assert_equals(dragexitCount, 0);
+ }));
+}, `dragexit must not fire during drag-and-drop`);
+</script>
diff --git a/testing/web-platform/tests/html/editing/dnd/events/relatedTarget-attribute-manual.html b/testing/web-platform/tests/html/editing/dnd/events/relatedTarget-attribute-manual.html
new file mode 100644
index 0000000000..c5a897d68e
--- /dev/null
+++ b/testing/web-platform/tests/html/editing/dnd/events/relatedTarget-attribute-manual.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<html>
+ <head>
+ <title>relatedTarget attribute for dragenter and dragleave events</title>
+ <meta name="viewport" content="width=device-width">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+ #outerdiv {
+ padding: 50px;
+ background: blue;
+ }
+ #innerdiv {
+ width:200px;
+ height:100px;
+ background: green;
+ }
+ </style>
+ <script>
+ var drag_test = async_test("dragenter and dragleave are correctly fired.");
+ var got_dragenter = false;
+ var got_dragleave = false;
+ function run() {
+ var draggable = document.getElementById("draggable");
+ var innerdiv = document.getElementById("innerdiv");
+ draggable.addEventListener("dragstart", (e) => {
+ e.dataTransfer.setData("text", draggable.innerHTML);
+ });
+ innerdiv.addEventListener("dragenter", (e) => {
+ if (!got_dragenter) {
+ test(function() {
+ assert_equals(e.relatedTarget.id, "outerdiv", "dragenter event should have the correct relatedTarget.");
+ }, "dragenter event should have the correct relatedTarget.");
+ got_dragenter = true;
+ }
+ });
+ innerdiv.addEventListener("dragleave", (e) => {
+ if (!got_dragleave) {
+ test(function() {
+ assert_equals(e.relatedTarget.id, "outerdiv", "dragleave event should have the correct relatedTarget.");
+ }, "dragleave event should have the correct relatedTarget.");
+ got_dragleave = true;
+ if (got_dragenter)
+ drag_test.done();
+ }
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Drag & Drop: relatedTarget attribute for dragenter and dragleave events</h1>
+ <h2 id="pointerTypeDescription"></h2>
+ <h4>Test Description:
+ <ol>
+ <li>Drag the text into the green box.</li>
+ <li>Without releasing the drag, drag the text out of the green box.</li>
+ </ol>
+ </h4>
+ <br>
+ <div id="draggable" draggable="true">Drag this text</br>over the green box</div>
+ <div id="outerdiv">
+ <div id="innerdiv"></div>
+ </div>
+ </body>
+</html>