focus.js
2.81 KB
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
82
83
84
85
// Support for element focus.
'use strict';
var DOM = require('./index');
var FOCUS_ELEMENTS = ['INPUT', 'SELECT', 'TEXTAREA', 'BUTTON', 'ANCHOR'];
// The element in focus.
//
// If no element has the focus, return the document.body.
DOM.HTMLDocument.prototype.__defineGetter__('activeElement', function () {
return this._inFocus || this.body;
});
// Change the current element in focus (or null for blur)
function setFocus(document, element) {
var inFocus = document._inFocus;
if (element !== inFocus) {
if (inFocus) {
var _onblur = document.createEvent('HTMLEvents');
_onblur.initEvent('blur', false, false);
inFocus.dispatchEvent(_onblur);
}
if (element) {
// null to blur
var _onfocus = document.createEvent('HTMLEvents');
_onfocus.initEvent('focus', false, false);
element.dispatchEvent(_onfocus);
document._inFocus = element;
document.defaultView.browser.emit('focus', element);
}
}
}
// All HTML elements have a no-op focus/blur methods.
DOM.HTMLElement.prototype.focus = function () {};
DOM.HTMLElement.prototype.blur = function () {};
// Input controls have active focus/blur elements. JSDOM implements these as
// no-op, so we have to over-ride each prototype individually.
var CONTROLS = [DOM.HTMLInputElement, DOM.HTMLSelectElement, DOM.HTMLTextAreaElement, DOM.HTMLButtonElement, DOM.HTMLAnchorElement];
CONTROLS.forEach(function (elementType) {
elementType.prototype.focus = function () {
setFocus(this.ownerDocument, this);
};
elementType.prototype.blur = function () {
setFocus(this.ownerDocument, null);
};
// Capture the autofocus element and use it to change focus
var setAttribute = elementType.prototype.setAttribute;
elementType.prototype.setAttribute = function (name, value) {
setAttribute.call(this, name, value);
if (name === 'autofocus') {
var _document = this.ownerDocument;
if (~FOCUS_ELEMENTS.indexOf(this.tagName) && !_document._inFocus) this.focus();
}
};
});
// When changing focus onto form control, store the current value. When changing
// focus to different control, if the value has changed, trigger a change event.
var INPUTS = [DOM.HTMLInputElement, DOM.HTMLTextAreaElement, DOM.HTMLSelectElement];
INPUTS.forEach(function (elementType) {
elementType.prototype._eventDefaults.focus = function (event) {
var element = event.target;
element._focusValue = element.value || '';
};
elementType.prototype._eventDefaults.blur = function (event) {
var element = event.target;
var focusValue = element._focusValue;
if (focusValue !== element.value) {
// null == undefined
var change = element.ownerDocument.createEvent('HTMLEvents');
change.initEvent('change', false, false);
element.dispatchEvent(change);
}
};
});
//# sourceMappingURL=focus.js.map