neft
Version:
JavaScript. Everywhere.
196 lines (164 loc) • 6.33 kB
text/coffeescript
'use strict'
signal = require 'src/signal'
module.exports = (impl) ->
implUtils = impl.utils
{round} = Math
SHEET = """
textarea, input[type=password] {
width: 100%;
height: 100%;
resize: none;
background: none;
border: none;
box-sizing: border-box;
font-size: 14px;
line-height: 1;
font-family: #{impl.utils.DEFAULT_FONTS['sans-serif']}, sans-serif;
}
input[type=password] {
padding-top: 0 !important;
}
"""
window.addEventListener 'load', ->
styles = document.createElement 'style'
styles.innerHTML = SHEET
document.body.appendChild styles
reloadFontFamily = (family) ->
if ( and ._family is family) or (not and family is 'sans-serif')
.innerElemStyle.fontFamily = .innerElemStyle.fontFamily
return
updateVerticalAlignment = (textInput) ->
data =
{verticalAlignment} = data
if verticalAlignment is 'top'
padding = 0
else
lineHeightPx = * (?._pixelSize or 14)
linesLength = (data.innerElem.value.match(/\n/g)?.length or 0) + 1
freeSpace = Math.max 0, - linesLength * lineHeightPx
if verticalAlignment is 'center'
padding = freeSpace / 2
else
padding = freeSpace
data.innerElemStyle.paddingTop = "#{padding}px"
DATA =
isMultiLine: false
textareaElem: null
innerElem: null
innerElemStyle: null
verticalAlignment: 'top'
DATA: DATA
createData: impl.utils.createDataCloner 'Item', DATA
create: (data) ->
self = @
impl.Types.Item.create.call @, data
# innerElem
innerElem = data.innerElem = data.textareaElem = document.createElement 'textarea'
data.innerElemStyle = innerElem.style
data.innerElemStyle.whiteSpace = 'nowrap'
data.elem.appendChild innerElem
# prevent scrollable on input
data.elem.addEventListener impl.utils.pointerWheelEventName, (e) ->
if data.isMultiLine and document.activeElement is innerElem
e.stopPropagation()
return
# prevent multi lines
data.elem.addEventListener 'keydown', (e) ->
if not data.isMultiLine and (window.event?.keyCode or e.which) is 13
e.preventDefault()
# manage focus
innerElem.addEventListener 'focus', (e) ->
self.keys.focus = true
unless self.keys.focus
e.preventDefault()
innerElem.addEventListener 'blur', (e) ->
self.keys.focus = false
.onFocusChange (oldVal) ->
data.innerElem[if !oldVal then 'focus' else 'blur']()
# update text
innerElem.addEventListener 'input', ->
{value} = innerElem
# prevent copying new lines
if not data.isMultiLine and /\n/.test(value)
value = value.replace /\n/g, ''
self.text = value
# set default size
impl.setItemWidth.call @, 100
impl.setItemHeight.call @, 50
# reload font on load
if impl.utils.loadingFonts['sans-serif'] > 0
impl.utils.onFontLoaded reloadFontFamily, @
# vertical alignment
updateVerticalAlignment
setTextInputText: (val) ->
if .innerElem.value isnt val
.innerElem.value = val
updateVerticalAlignment.call @
return
setTextInputColor: (val) ->
.innerElemStyle.color = val
return
setTextInputLineHeight: (val) ->
.innerElemStyle.lineHeight = val
return
setTextInputMultiLine: (val) ->
data =
data.isMultiLine = val
data.innerElemStyle.whiteSpace = 'nowrap'
unless val
= .replace /\n/g, ''
return
setTextInputEchoMode: (val) ->
self = @
data =
switch val
when 'normal'
data.elem.removeChild data.innerElem
if
implUtils.insertAfter data.innerElem, ._impl.elem
else
implUtils.prependElement data.elem, data.textareaElem
data.textareaElem.setAttribute 'style', data.innerElem.getAttribute('style')
data.innerElem = data.textareaElem
data.innerElemStyle = data.textareaElem.style
when 'password'
input = document.createElement 'input'
input.setAttribute 'type', 'password'
input.setAttribute 'style', data.innerElem.getAttribute('style')
data.elem.removeChild data.innerElem
if
implUtils.insertAfter input, ._impl.elem
else
implUtils.prependElement data.elem, input
data.innerElem = input
data.innerElemStyle = input.style
input.addEventListener 'input', ->
self.text = input.value
return
return
setTextInputFontFamily: (val) ->
if impl.utils.loadingFonts[val] > 0
impl.utils.onFontLoaded reloadFontFamily, @
if impl.utils.DEFAULT_FONTS[val]
val = "#{impl.utils.DEFAULT_FONTS[val]}, #{val}"
else
val = "'#{val}'"
.innerElemStyle.fontFamily = val
return
setTextInputFontPixelSize: (val) ->
val = round val
.innerElemStyle.fontSize = "#{val}px"
return
setTextInputFontWordSpacing: (val) ->
.innerElemStyle.wordSpacing = "#{val}px"
return
setTextInputFontLetterSpacing: (val) ->
.innerElemStyle.letterSpacing = "#{val}px"
return
setTextInputAlignmentHorizontal: (val) ->
.innerElemStyle.textAlign = val
return
setTextInputAlignmentVertical: (val) ->
.verticalAlignment = val
updateVerticalAlignment.call @
return