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