Dragon Drop
Dragon Drop provides precise drag-and-drop capability to arbitrary HTML elements within, around, and between contenteditable dropzones. Dragon Drop is the result of Chase Moskal's investigation into the scary, mysterious world of HTML5's Drag and Drop API. It's a total disaster (the API that is). The techniques employed by Dragon Drop to make this functionality work on both Firefox as well as Chrome are, unfortunately necessarily, very hacky. Nonetheless, the creation of Dragon Drop has been the only successful way to achieve satisfactory Firefox and Chrome functionality. StackOverflow Post: http://stackoverflow.com/questions/14678451/precise-drag-and-drop-within-a-contenteditable
by jadiagaurang
HTML
<div contenteditable="true">
<h1>Athenagora Lenoni Incommunicabile: Structured Content</h1>
<h2>Cellam modico illius ergo accipiet si non ait est Apollonius.</h2>
<a class="fancy" style="display:none;">
<img src="http://placehold.it/150x150" />
<caption>Hola!</caption>
</a>
<p class="fancy">Volvitur ingreditur lavare propter increparet videns mihi cum. Tharsis ratio puella est Apollonius in deinde plectrum anni ipsa codicellos, jesus Circumdat flante vestibus lumine restat paralyticus audi anim igitur patriam Dianae. 'Iuraveras magnifice</p>
<p class="fancy">ex quae ad per te sed dominum sit Mariae Bone de his carpens introivit filiam. Plus damna nautis unum ad te. Puto suam ad quia iuvenis omnia. Etiam quantitas devenit regi adhibitis sedens loculum inveni.</p>
</div>
<div contenteditable="true">
<p><strong>Unstructured Content:</strong> Toto determinata se est se ad te finis laeta gavisus, laetare quod una non ait mea ego dum est Apollonius. Intrarem puella est in deinde cupis ei Taliarchum in, tharsiam vis interrogat Verena est Apollonius eius
ad suis. Antiochus ac esse more filiam sunt forma ait Cumque persequatur sic. Imas rebum accusam in fuerat est se sed esse ait Cumque ego. Secundis sacerdotem habemus ibi alteri ad quia, agere videre Proicite a civitas exulto haec. Supponite facultatibus
actum dixit eos. Neminem habere litore in deinde duas formis. Quattuordecim anulum ad nomine Hesterna studiis ascende meae puer ut sua, eiusdem ordo quos annorum afferte Apollonius non ait in.
<br />
<br /> Deducitur potest contremiscunt eum ego Pentapolim Cyrenaeorum tertia navigavit volente in fuerat eum istam vero cum obiectum invidunt cum. Christe in rei sensibilium iussit sed, scitote si quod ait Cumque persequatur sic. Amet consensit cellula filia
in rei civibus laude clamaverunt donavit potest flens non solutionem innocentem si quod ait. Una Christi sanguine concomitatur quia quod non coepit, volvitur ingreditur est...
CSS
/*====== DragonDrop Demo CSS
Basically, user-select, and user-drag (and all their prefixes) need to be set in a way that lets the browser know which parts of our draggable element are selectable and draggable and which aren't.
So I guess this is that.
======*/
@charset utf-8;
/* these rules only apply to fancy boxes when contenteditable is true: they are necessary for the drag-and-drop demo to work correctly */
[contenteditable="true"] .fancy {
/**/
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
/* without this line, element can be dragged within itself! No-no! */
/**/
-moz-user-drag: element;
-webkit-user-drag: element;
user-drag: element;
/* makes the whole fancy box draggable */
cursor: move !important;
}
/* switches to the move cursor */
[contenteditable="true"] .fancy * {
/**/
-moz-user-drag: none;
-webkit-user-drag: none;
user-drag: none;
}
/* hopefully disables the internal default dragging of the img */
/*====== Everything below this area
is STRICLY for STYLE
and VISUAL APPEAL.
It shouldn't concern you. ======*/
html,
body {
height: 100%;
}
[contenteditable] {
background: #f8f8f8;
box-sizing: border-box;
padding: 2%;
min-height: auto;
font-size: 10px;
font-family: sans-serif;
color: #444;
border-bottom: 2px dashed #888;
}
.fancy {
display: inline-block;
margin: 10px;
color: #444;
text-align: center;
font-style: italic;
font-size: 10px;
font-family: sans-serif;
background: #fff;
border: 8px solid white;
box-shadow: 1px 2px 8px #444;
cursor: pointer;
}
.fancy img {
display: block;
margin-bottom: 2px;
border: 1px solid white;
box-shadow: 0 1px 6px #888;
}
.fancy .caption {
max-width: 100px;
}
h1 {
font-weight: bold;
font-size: 1.4em;
}
h2 {
font-weight: bold;
font-style: italic;
text-indent: 2px;
}
p {
text-indent: 8px;
}
strong {
font-weight:...
JavaScript
/*
==== Dragon Drop: a demo of precise DnD
in, around, and between
multiple contenteditable's.
=================================
== MIT Licensed for all to use ==
=================================
Copyright (C) 2013 Chase Moskal
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
============
*/
function DRAGON_DROP(o) {
var DD = this;
// "o" params:
DD.$draggables = null;
DD.$dropzones = null;
DD.$noDrags = null; // optional
DD.dropLoad = null;
DD.engage = function(o) {
DD.$draggables = $(o.draggables);
DD.$dropzones = $(o.dropzones);
DD.$draggables.attr('draggable', 'true');
DD.$noDrags = (o.noDrags) ? $(o.noDrags) : $();
DD.$dropzones.attr('dropzone', 'copy');
DD.bindDraggables();
DD.bindDropzones();
};
DD.bindDraggables = function() {
DD.$draggables = $(DD.$draggables.selector); // reselecting
DD.$noDrags = $(DD.$noDrags.selector);
DD.$noDrags.attr('draggable', 'false');
DD.$draggables.off('dragstart').on('dragstart',...