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