-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.ts
81 lines (65 loc) · 2.18 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/// <reference path='types.d.ts' />
/**
* Module dependencies.
*/
import setRange = require('selection-set-range');
import isBackward = require('selection-is-backward');
import currentRange = require('current-range');
import currentSelection = require('current-selection');
/**
* DOM based "paste" event handler.
*
* @public
*/
function domPaste(e: Event, callback: (data: HTMLElement) => void) {
// TODO: use `get-document` here
var doc: Document = document;
var selection: Selection = currentSelection(doc);
var backward: boolean = isBackward(selection);
var range: Range = currentRange(selection);
var activeElement = <HTMLElement>doc.activeElement;
// create temporary content editable contaner
var container: HTMLElement = doc.createElement('div');
container.contentEditable = 'true';
container.style.position = 'fixed';
container.style.overflow = 'hidden';
container.style.width = container.style.height = container.style.top = container.style.left = '0px';
var br: HTMLElement = doc.createElement('br'); // needed by Firefox
container.appendChild(br);
doc.body.appendChild(container);
// observer for dom mutations in container
var observer = new MutationObserver(function() {
// remove br element, if it's still there (Firefox fix)
if (br.parentNode) {
br.parentNode.removeChild(br);
}
// restore focus and original selection range
activeElement.focus();
if (range) {
setRange(selection, range, backward);
}
// avoid having handler fire again if changes
// are made within the callback
observer.disconnect();
try {
callback(container);
} finally {
// remove temporary container
doc.body.removeChild(container);
}
});
observer.observe(container, {
childList: true,
attributes: true,
characterData: true,
subtree: true
});
// move focus and selection to temporary container
container.focus();
var selector: Range = doc.createRange();
selector.selectNodeContents(container);
setRange(selection, selector, false);
// default paste behaviour will be handled by the browser inside the container,
// triggering the mutation event.
}
export = domPaste;