dialog.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: https://codemirror.net/LICENSE
  3. // Open simple dialogs on top of an editor. Relies on dialog.css.
  4. ;(function (mod) {
  5. if (typeof exports == 'object' && typeof module == 'object')
  6. // CommonJS
  7. mod(require('../../lib/codemirror'))
  8. else if (typeof define == 'function' && define.amd)
  9. // AMD
  10. define(['../../lib/codemirror'], mod)
  11. // Plain browser env
  12. else mod(CodeMirror)
  13. })(function (CodeMirror) {
  14. function dialogDiv(cm, template, bottom) {
  15. var wrap = cm.getWrapperElement()
  16. var dialog
  17. dialog = wrap.appendChild(document.createElement('div'))
  18. if (bottom) dialog.className = 'CodeMirror-dialog CodeMirror-dialog-bottom'
  19. else dialog.className = 'CodeMirror-dialog CodeMirror-dialog-top'
  20. if (typeof template == 'string') {
  21. dialog.innerHTML = template
  22. } else {
  23. // Assuming it's a detached DOM element.
  24. dialog.appendChild(template)
  25. }
  26. CodeMirror.addClass(wrap, 'dialog-opened')
  27. return dialog
  28. }
  29. function closeNotification(cm, newVal) {
  30. if (cm.state.currentNotificationClose) cm.state.currentNotificationClose()
  31. cm.state.currentNotificationClose = newVal
  32. }
  33. CodeMirror.defineExtension('openDialog', function (template, callback, options) {
  34. if (!options) options = {}
  35. closeNotification(this, null)
  36. var dialog = dialogDiv(this, template, options.bottom)
  37. var closed = false,
  38. me = this
  39. function close(newVal) {
  40. if (typeof newVal == 'string') {
  41. inp.value = newVal
  42. } else {
  43. if (closed) return
  44. closed = true
  45. CodeMirror.rmClass(dialog.parentNode, 'dialog-opened')
  46. dialog.parentNode.removeChild(dialog)
  47. me.focus()
  48. if (options.onClose) options.onClose(dialog)
  49. }
  50. }
  51. var inp = dialog.getElementsByTagName('input')[0],
  52. button
  53. if (inp) {
  54. inp.focus()
  55. if (options.value) {
  56. inp.value = options.value
  57. if (options.selectValueOnOpen !== false) {
  58. inp.select()
  59. }
  60. }
  61. if (options.onInput)
  62. CodeMirror.on(inp, 'input', function (e) {
  63. options.onInput(e, inp.value, close)
  64. })
  65. if (options.onKeyUp)
  66. CodeMirror.on(inp, 'keyup', function (e) {
  67. options.onKeyUp(e, inp.value, close)
  68. })
  69. CodeMirror.on(inp, 'keydown', function (e) {
  70. if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) {
  71. return
  72. }
  73. if (e.keyCode == 27 || (options.closeOnEnter !== false && e.keyCode == 13)) {
  74. inp.blur()
  75. CodeMirror.e_stop(e)
  76. close()
  77. }
  78. if (e.keyCode == 13) callback(inp.value, e)
  79. })
  80. if (options.closeOnBlur !== false)
  81. CodeMirror.on(dialog, 'focusout', function (evt) {
  82. if (evt.relatedTarget !== null) close()
  83. })
  84. } else if ((button = dialog.getElementsByTagName('button')[0])) {
  85. CodeMirror.on(button, 'click', function () {
  86. close()
  87. me.focus()
  88. })
  89. if (options.closeOnBlur !== false) CodeMirror.on(button, 'blur', close)
  90. button.focus()
  91. }
  92. return close
  93. })
  94. CodeMirror.defineExtension('openConfirm', function (template, callbacks, options) {
  95. closeNotification(this, null)
  96. var dialog = dialogDiv(this, template, options && options.bottom)
  97. var buttons = dialog.getElementsByTagName('button')
  98. var closed = false,
  99. me = this,
  100. blurring = 1
  101. function close() {
  102. if (closed) return
  103. closed = true
  104. CodeMirror.rmClass(dialog.parentNode, 'dialog-opened')
  105. dialog.parentNode.removeChild(dialog)
  106. me.focus()
  107. }
  108. buttons[0].focus()
  109. for (var i = 0; i < buttons.length; ++i) {
  110. var b = buttons[i]
  111. ;(function (callback) {
  112. CodeMirror.on(b, 'click', function (e) {
  113. CodeMirror.e_preventDefault(e)
  114. close()
  115. if (callback) callback(me)
  116. })
  117. })(callbacks[i])
  118. CodeMirror.on(b, 'blur', function () {
  119. --blurring
  120. setTimeout(function () {
  121. if (blurring <= 0) close()
  122. }, 200)
  123. })
  124. CodeMirror.on(b, 'focus', function () {
  125. ++blurring
  126. })
  127. }
  128. })
  129. /*
  130. * openNotification
  131. * Opens a notification, that can be closed with an optional timer
  132. * (default 5000ms timer) and always closes on click.
  133. *
  134. * If a notification is opened while another is opened, it will close the
  135. * currently opened one and open the new one immediately.
  136. */
  137. CodeMirror.defineExtension('openNotification', function (template, options) {
  138. closeNotification(this, close)
  139. var dialog = dialogDiv(this, template, options && options.bottom)
  140. var closed = false,
  141. doneTimer
  142. var duration = options && typeof options.duration !== 'undefined' ? options.duration : 5000
  143. function close() {
  144. if (closed) return
  145. closed = true
  146. clearTimeout(doneTimer)
  147. CodeMirror.rmClass(dialog.parentNode, 'dialog-opened')
  148. dialog.parentNode.removeChild(dialog)
  149. }
  150. CodeMirror.on(dialog, 'click', function (e) {
  151. CodeMirror.e_preventDefault(e)
  152. close()
  153. })
  154. if (duration) doneTimer = setTimeout(close, duration)
  155. return close
  156. })
  157. })