-
-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathindex.js
84 lines (76 loc) · 3.62 KB
/
index.js
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
var GHOST_ELEMENT_ID = '__autosizeInputGhost'
var characterEntities = {
' ': 'nbsp',
'<': 'lt',
'>': 'gt'
}
function mapSpecialCharacterToCharacterEntity (specialCharacter) {
return '&' + characterEntities[specialCharacter] + ';'
}
function escapeSpecialCharacters (string) {
return string.replace(/\s|<|>/g, mapSpecialCharacterToCharacterEntity)
}
// Create `ghostElement`, with inline styles to hide it and ensure that the text is all
// on a single line.
function createGhostElement () {
var ghostElement = document.createElement('div')
ghostElement.id = GHOST_ELEMENT_ID
ghostElement.style.cssText =
'display:inline-block;height:0;overflow:hidden;position:absolute;top:0;visibility:hidden;white-space:nowrap;'
document.body.appendChild(ghostElement)
return ghostElement
}
module.exports = function (element, options) {
var elementStyle = window.getComputedStyle(element)
// prettier-ignore
var elementCssText = 'box-sizing:' + elementStyle.boxSizing +
';border-left:' + elementStyle.borderLeftWidth + ' solid red' +
';border-right:' + elementStyle.borderRightWidth + ' solid red' +
';font-family:' + elementStyle.fontFamily +
';font-feature-settings:' + elementStyle.fontFeatureSettings +
';font-kerning:' + elementStyle.fontKerning +
';font-size:' + elementStyle.fontSize +
';font-stretch:' + elementStyle.fontStretch +
';font-style:' + elementStyle.fontStyle +
';font-variant:' + elementStyle.fontVariant +
';font-variant-caps:' + elementStyle.fontVariantCaps +
';font-variant-ligatures:' + elementStyle.fontVariantLigatures +
';font-variant-numeric:' + elementStyle.fontVariantNumeric +
';font-weight:' + elementStyle.fontWeight +
';letter-spacing:' + elementStyle.letterSpacing +
';margin-left:' + elementStyle.marginLeft +
';margin-right:' + elementStyle.marginRight +
';padding-left:' + elementStyle.paddingLeft +
';padding-right:' + elementStyle.paddingRight +
';text-indent:' + elementStyle.textIndent +
';text-transform:' + elementStyle.textTransform
// Assigns an appropriate width to the given `element` based on its contents.
function setWidth () {
var string = element.value || element.getAttribute('placeholder') || ''
// Check if the `ghostElement` exists. If no, create it.
var ghostElement =
document.getElementById(GHOST_ELEMENT_ID) || createGhostElement()
// Copy all width-affecting styles to the `ghostElement`.
ghostElement.style.cssText += elementCssText
ghostElement.innerHTML = escapeSpecialCharacters(string)
// Copy the width of `ghostElement` to `element`.
var width = window.getComputedStyle(ghostElement).width
element.style.width = width
return width
}
element.addEventListener('input', setWidth)
var width = setWidth()
// Set `min-width` only if `options.minWidth` was set, and only if the initial
// width is non-zero.
if (options && options.minWidth && width !== '0px') {
element.style.minWidth = width
}
// Return a function for unbinding the event listener and removing the `ghostElement`.
return function () {
element.removeEventListener('input', setWidth)
var ghostElement = document.getElementById(GHOST_ELEMENT_ID)
if (ghostElement) {
ghostElement.parentNode.removeChild(ghostElement)
}
}
}