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