placeholder.js 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: https://codemirror.net/LICENSE
  3. ;(function (mod) {
  4. if (typeof exports == 'object' && typeof module == 'object')
  5. // CommonJS
  6. mod(require('../../lib/codemirror'))
  7. else if (typeof define == 'function' && define.amd)
  8. // AMD
  9. define(['../../lib/codemirror'], mod)
  10. // Plain browser env
  11. else mod(CodeMirror)
  12. })(function (CodeMirror) {
  13. CodeMirror.defineOption('placeholder', '', function (cm, val, old) {
  14. var prev = old && old != CodeMirror.Init
  15. if (val && !prev) {
  16. cm.on('blur', onBlur)
  17. cm.on('change', onChange)
  18. cm.on('swapDoc', onChange)
  19. CodeMirror.on(
  20. cm.getInputField(),
  21. 'compositionupdate',
  22. (cm.state.placeholderCompose = function () {
  23. onComposition(cm)
  24. })
  25. )
  26. onChange(cm)
  27. } else if (!val && prev) {
  28. cm.off('blur', onBlur)
  29. cm.off('change', onChange)
  30. cm.off('swapDoc', onChange)
  31. CodeMirror.off(cm.getInputField(), 'compositionupdate', cm.state.placeholderCompose)
  32. clearPlaceholder(cm)
  33. var wrapper = cm.getWrapperElement()
  34. wrapper.className = wrapper.className.replace(' CodeMirror-empty', '')
  35. }
  36. if (val && !cm.hasFocus()) onBlur(cm)
  37. })
  38. function clearPlaceholder(cm) {
  39. if (cm.state.placeholder) {
  40. cm.state.placeholder.parentNode.removeChild(cm.state.placeholder)
  41. cm.state.placeholder = null
  42. }
  43. }
  44. function setPlaceholder(cm) {
  45. clearPlaceholder(cm)
  46. var elt = (cm.state.placeholder = document.createElement('pre'))
  47. elt.style.cssText = 'height: 0; overflow: visible'
  48. elt.style.direction = cm.getOption('direction')
  49. elt.className = 'CodeMirror-placeholder CodeMirror-line-like'
  50. var placeHolder = cm.getOption('placeholder')
  51. if (typeof placeHolder == 'string') placeHolder = document.createTextNode(placeHolder)
  52. elt.appendChild(placeHolder)
  53. cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild)
  54. }
  55. function onComposition(cm) {
  56. setTimeout(function () {
  57. var empty = false
  58. if (cm.lineCount() == 1) {
  59. var input = cm.getInputField()
  60. empty = input.nodeName == 'TEXTAREA' ? !cm.getLine(0).length : !/[^\u200b]/.test(input.querySelector('.CodeMirror-line').textContent)
  61. }
  62. if (empty) setPlaceholder(cm)
  63. else clearPlaceholder(cm)
  64. }, 20)
  65. }
  66. function onBlur(cm) {
  67. if (isEmpty(cm)) setPlaceholder(cm)
  68. }
  69. function onChange(cm) {
  70. var wrapper = cm.getWrapperElement(),
  71. empty = isEmpty(cm)
  72. wrapper.className = wrapper.className.replace(' CodeMirror-empty', '') + (empty ? ' CodeMirror-empty' : '')
  73. if (empty) setPlaceholder(cm)
  74. else clearPlaceholder(cm)
  75. }
  76. function isEmpty(cm) {
  77. return cm.lineCount() === 1 && cm.getLine(0) === ''
  78. }
  79. })