bee_api 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/bee_api +84 -0
- data/lib/mdpreview.rb +80 -0
- data/lib/mdpreview/translator.rb +60 -0
- data/lib/mdpreview/version.rb +3 -0
- data/test/mdptest.rb +100 -0
- data/vendor/HISTORY.md +237 -0
- data/vendor/Jakefile.js +316 -0
- data/vendor/LICENSE +176 -0
- data/vendor/NOTICE +17 -0
- data/vendor/README.md +102 -0
- data/vendor/app/chrome/documentation.txt +12 -0
- data/vendor/app/chrome/manifest.json +24 -0
- data/vendor/app/web/ajax.js +43 -0
- data/vendor/app/web/app.css +292 -0
- data/vendor/app/web/app.js +377 -0
- data/vendor/app/web/beta/index.html +17 -0
- data/vendor/app/web/datapolicy.txt +48 -0
- data/vendor/app/web/doc/doc.css +60 -0
- data/vendor/app/web/doc/img/actions_menu.png +0 -0
- data/vendor/app/web/doc/img/button_actions_menu.png +0 -0
- data/vendor/app/web/doc/img/button_dragarea.png +0 -0
- data/vendor/app/web/doc/img/jsoneditor.png +0 -0
- data/vendor/app/web/doc/img/jsonformatter.png +0 -0
- data/vendor/app/web/doc/img/main_menu.png +0 -0
- data/vendor/app/web/doc/img/splitter.png +0 -0
- data/vendor/app/web/doc/index.html +201 -0
- data/vendor/app/web/favicon.ico +0 -0
- data/vendor/app/web/fileretriever.css +54 -0
- data/vendor/app/web/fileretriever.js +567 -0
- data/vendor/app/web/fileretriever.php +120 -0
- data/vendor/app/web/googlea47c4a0b36d11021.html +1 -0
- data/vendor/app/web/hash.js +133 -0
- data/vendor/app/web/img/description.txt +20 -0
- data/vendor/app/web/img/header_background.png +0 -0
- data/vendor/app/web/img/icon_128.png +0 -0
- data/vendor/app/web/img/icon_16.png +0 -0
- data/vendor/app/web/img/icon_gray.svg +151 -0
- data/vendor/app/web/img/icon_gray_16.svg +150 -0
- data/vendor/app/web/img/icon_orange.svg +151 -0
- data/vendor/app/web/img/logo.png +0 -0
- data/vendor/app/web/img/logo.xcf +0 -0
- data/vendor/app/web/img/logo_app.png +0 -0
- data/vendor/app/web/img/logo_app.xcf +0 -0
- data/vendor/app/web/index.html +191 -0
- data/vendor/app/web/notify.js +150 -0
- data/vendor/app/web/queryparams.js +71 -0
- data/vendor/app/web/robots.txt +0 -0
- data/vendor/app/web/splitter.js +179 -0
- data/vendor/app/web/test.html +224 -0
- data/vendor/component.json +33 -0
- data/vendor/docs/api.md +188 -0
- data/vendor/docs/usage.md +137 -0
- data/vendor/examples/01_basic_usage.html +45 -0
- data/vendor/examples/02_viewer.html +38 -0
- data/vendor/examples/03_switch_mode.html +98 -0
- data/vendor/examples/cur.file +1 -0
- data/vendor/examples/jquery.js +2 -0
- data/vendor/examples/meta.js +1 -0
- data/vendor/examples/requirejs_demo/requirejs_demo.html +19 -0
- data/vendor/examples/requirejs_demo/scripts/main.js +25 -0
- data/vendor/examples/requirejs_demo/scripts/require.js +35 -0
- data/vendor/img/jsoneditor-icons.png +0 -0
- data/vendor/jsoneditor-min.css +1 -0
- data/vendor/jsoneditor-min.js +34 -0
- data/vendor/jsoneditor.css +597 -0
- data/vendor/jsoneditor.js +6069 -0
- data/vendor/jsoneditor/css/contextmenu.css +219 -0
- data/vendor/jsoneditor/css/img/description.txt +13 -0
- data/vendor/jsoneditor/css/img/export.sh +16 -0
- data/vendor/jsoneditor/css/img/jsoneditor-icons.png +0 -0
- data/vendor/jsoneditor/css/img/jsoneditor-icons.svg +861 -0
- data/vendor/jsoneditor/css/jsoneditor.css +220 -0
- data/vendor/jsoneditor/css/menu.css +81 -0
- data/vendor/jsoneditor/css/searchbox.css +73 -0
- data/vendor/jsoneditor/js/appendnode.js +211 -0
- data/vendor/jsoneditor/js/contextmenu.js +440 -0
- data/vendor/jsoneditor/js/header.js +32 -0
- data/vendor/jsoneditor/js/highlighter.js +82 -0
- data/vendor/jsoneditor/js/history.js +218 -0
- data/vendor/jsoneditor/js/jsoneditor.js +206 -0
- data/vendor/jsoneditor/js/module.js +50 -0
- data/vendor/jsoneditor/js/node.js +2864 -0
- data/vendor/jsoneditor/js/searchbox.js +288 -0
- data/vendor/jsoneditor/js/texteditor.js +311 -0
- data/vendor/jsoneditor/js/treeeditor.js +770 -0
- data/vendor/jsoneditor/js/util.js +582 -0
- data/vendor/lib/ace/ace.js +11 -0
- data/vendor/lib/ace/mode-json.js +1 -0
- data/vendor/lib/ace/theme-jsoneditor.js +144 -0
- data/vendor/lib/ace/theme-textmate.js +163 -0
- data/vendor/lib/ace/worker-json.js +1 -0
- data/vendor/lib/jsonlint/README.md +62 -0
- data/vendor/lib/jsonlint/jsonlint.js +432 -0
- data/vendor/misc/screenshots/actionsmenu_640x400.png +0 -0
- data/vendor/misc/screenshots/codeeditor_640x400.png +0 -0
- data/vendor/misc/screenshots/description.json +17 -0
- data/vendor/misc/screenshots/jsoneditoronline.png +0 -0
- data/vendor/misc/screenshots/jsoneditoronline_640x400.png +0 -0
- data/vendor/misc/screenshots/search_640x400.png +0 -0
- data/vendor/misc/screenshots/small_tile.xcf +0 -0
- data/vendor/misc/screenshots/small_tile_440x280.png +0 -0
- data/vendor/misc/todo.txt +101 -0
- data/vendor/package.json +28 -0
- data/vendor/test/couchdbeditor.html +100 -0
- data/vendor/test/largefile.json +12605 -0
- data/vendor/test/test_ace.html +60 -0
- data/vendor/test/test_editable_div.html +449 -0
- metadata +154 -0
@@ -0,0 +1,288 @@
|
|
1
|
+
/**
|
2
|
+
* @constructor SearchBox
|
3
|
+
* Create a search box in given HTML container
|
4
|
+
* @param {JSONEditor} editor The JSON Editor to attach to
|
5
|
+
* @param {Element} container HTML container element of where to
|
6
|
+
* create the search box
|
7
|
+
*/
|
8
|
+
function SearchBox (editor, container) {
|
9
|
+
var searchBox = this;
|
10
|
+
|
11
|
+
this.editor = editor;
|
12
|
+
this.timeout = undefined;
|
13
|
+
this.delay = 200; // ms
|
14
|
+
this.lastText = undefined;
|
15
|
+
|
16
|
+
this.dom = {};
|
17
|
+
this.dom.container = container;
|
18
|
+
|
19
|
+
var table = document.createElement('table');
|
20
|
+
this.dom.table = table;
|
21
|
+
table.className = 'search';
|
22
|
+
container.appendChild(table);
|
23
|
+
var tbody = document.createElement('tbody');
|
24
|
+
this.dom.tbody = tbody;
|
25
|
+
table.appendChild(tbody);
|
26
|
+
var tr = document.createElement('tr');
|
27
|
+
tbody.appendChild(tr);
|
28
|
+
|
29
|
+
var td = document.createElement('td');
|
30
|
+
tr.appendChild(td);
|
31
|
+
var results = document.createElement('div');
|
32
|
+
this.dom.results = results;
|
33
|
+
results.className = 'results';
|
34
|
+
td.appendChild(results);
|
35
|
+
|
36
|
+
td = document.createElement('td');
|
37
|
+
tr.appendChild(td);
|
38
|
+
var divInput = document.createElement('div');
|
39
|
+
this.dom.input = divInput;
|
40
|
+
divInput.className = 'frame';
|
41
|
+
divInput.title = 'Search fields and values';
|
42
|
+
td.appendChild(divInput);
|
43
|
+
|
44
|
+
// table to contain the text input and search button
|
45
|
+
var tableInput = document.createElement('table');
|
46
|
+
divInput.appendChild(tableInput);
|
47
|
+
var tbodySearch = document.createElement('tbody');
|
48
|
+
tableInput.appendChild(tbodySearch);
|
49
|
+
tr = document.createElement('tr');
|
50
|
+
tbodySearch.appendChild(tr);
|
51
|
+
|
52
|
+
var refreshSearch = document.createElement('button');
|
53
|
+
refreshSearch.className = 'refresh';
|
54
|
+
td = document.createElement('td');
|
55
|
+
td.appendChild(refreshSearch);
|
56
|
+
tr.appendChild(td);
|
57
|
+
|
58
|
+
var search = document.createElement('input');
|
59
|
+
this.dom.search = search;
|
60
|
+
search.oninput = function (event) {
|
61
|
+
searchBox._onDelayedSearch(event);
|
62
|
+
};
|
63
|
+
search.onchange = function (event) { // For IE 8
|
64
|
+
searchBox._onSearch(event);
|
65
|
+
};
|
66
|
+
search.onkeydown = function (event) {
|
67
|
+
searchBox._onKeyDown(event);
|
68
|
+
};
|
69
|
+
search.onkeyup = function (event) {
|
70
|
+
searchBox._onKeyUp(event);
|
71
|
+
};
|
72
|
+
refreshSearch.onclick = function (event) {
|
73
|
+
search.select();
|
74
|
+
};
|
75
|
+
|
76
|
+
// TODO: ESC in FF restores the last input, is a FF bug, https://bugzilla.mozilla.org/show_bug.cgi?id=598819
|
77
|
+
td = document.createElement('td');
|
78
|
+
td.appendChild(search);
|
79
|
+
tr.appendChild(td);
|
80
|
+
|
81
|
+
var searchNext = document.createElement('button');
|
82
|
+
searchNext.title = 'Next result (Enter)';
|
83
|
+
searchNext.className = 'next';
|
84
|
+
searchNext.onclick = function () {
|
85
|
+
searchBox.next();
|
86
|
+
};
|
87
|
+
td = document.createElement('td');
|
88
|
+
td.appendChild(searchNext);
|
89
|
+
tr.appendChild(td);
|
90
|
+
|
91
|
+
var searchPrevious = document.createElement('button');
|
92
|
+
searchPrevious.title = 'Previous result (Shift+Enter)';
|
93
|
+
searchPrevious.className = 'previous';
|
94
|
+
searchPrevious.onclick = function () {
|
95
|
+
searchBox.previous();
|
96
|
+
};
|
97
|
+
td = document.createElement('td');
|
98
|
+
td.appendChild(searchPrevious);
|
99
|
+
tr.appendChild(td);
|
100
|
+
}
|
101
|
+
|
102
|
+
/**
|
103
|
+
* Go to the next search result
|
104
|
+
* @param {boolean} [focus] If true, focus will be set to the next result
|
105
|
+
* focus is false by default.
|
106
|
+
*/
|
107
|
+
SearchBox.prototype.next = function(focus) {
|
108
|
+
if (this.results != undefined) {
|
109
|
+
var index = (this.resultIndex != undefined) ? this.resultIndex + 1 : 0;
|
110
|
+
if (index > this.results.length - 1) {
|
111
|
+
index = 0;
|
112
|
+
}
|
113
|
+
this._setActiveResult(index, focus);
|
114
|
+
}
|
115
|
+
};
|
116
|
+
|
117
|
+
/**
|
118
|
+
* Go to the prevous search result
|
119
|
+
* @param {boolean} [focus] If true, focus will be set to the next result
|
120
|
+
* focus is false by default.
|
121
|
+
*/
|
122
|
+
SearchBox.prototype.previous = function(focus) {
|
123
|
+
if (this.results != undefined) {
|
124
|
+
var max = this.results.length - 1;
|
125
|
+
var index = (this.resultIndex != undefined) ? this.resultIndex - 1 : max;
|
126
|
+
if (index < 0) {
|
127
|
+
index = max;
|
128
|
+
}
|
129
|
+
this._setActiveResult(index, focus);
|
130
|
+
}
|
131
|
+
};
|
132
|
+
|
133
|
+
/**
|
134
|
+
* Set new value for the current active result
|
135
|
+
* @param {Number} index
|
136
|
+
* @param {boolean} [focus] If true, focus will be set to the next result.
|
137
|
+
* focus is false by default.
|
138
|
+
* @private
|
139
|
+
*/
|
140
|
+
SearchBox.prototype._setActiveResult = function(index, focus) {
|
141
|
+
// de-activate current active result
|
142
|
+
if (this.activeResult) {
|
143
|
+
var prevNode = this.activeResult.node;
|
144
|
+
var prevElem = this.activeResult.elem;
|
145
|
+
if (prevElem == 'field') {
|
146
|
+
delete prevNode.searchFieldActive;
|
147
|
+
}
|
148
|
+
else {
|
149
|
+
delete prevNode.searchValueActive;
|
150
|
+
}
|
151
|
+
prevNode.updateDom();
|
152
|
+
}
|
153
|
+
|
154
|
+
if (!this.results || !this.results[index]) {
|
155
|
+
// out of range, set to undefined
|
156
|
+
this.resultIndex = undefined;
|
157
|
+
this.activeResult = undefined;
|
158
|
+
return;
|
159
|
+
}
|
160
|
+
|
161
|
+
this.resultIndex = index;
|
162
|
+
|
163
|
+
// set new node active
|
164
|
+
var node = this.results[this.resultIndex].node;
|
165
|
+
var elem = this.results[this.resultIndex].elem;
|
166
|
+
if (elem == 'field') {
|
167
|
+
node.searchFieldActive = true;
|
168
|
+
}
|
169
|
+
else {
|
170
|
+
node.searchValueActive = true;
|
171
|
+
}
|
172
|
+
this.activeResult = this.results[this.resultIndex];
|
173
|
+
node.updateDom();
|
174
|
+
|
175
|
+
// TODO: not so nice that the focus is only set after the animation is finished
|
176
|
+
node.scrollTo(function () {
|
177
|
+
if (focus) {
|
178
|
+
node.focus(elem);
|
179
|
+
}
|
180
|
+
});
|
181
|
+
};
|
182
|
+
|
183
|
+
/**
|
184
|
+
* Cancel any running onDelayedSearch.
|
185
|
+
* @private
|
186
|
+
*/
|
187
|
+
SearchBox.prototype._clearDelay = function() {
|
188
|
+
if (this.timeout != undefined) {
|
189
|
+
clearTimeout(this.timeout);
|
190
|
+
delete this.timeout;
|
191
|
+
}
|
192
|
+
};
|
193
|
+
|
194
|
+
/**
|
195
|
+
* Start a timer to execute a search after a short delay.
|
196
|
+
* Used for reducing the number of searches while typing.
|
197
|
+
* @param {Event} event
|
198
|
+
* @private
|
199
|
+
*/
|
200
|
+
SearchBox.prototype._onDelayedSearch = function (event) {
|
201
|
+
// execute the search after a short delay (reduces the number of
|
202
|
+
// search actions while typing in the search text box)
|
203
|
+
this._clearDelay();
|
204
|
+
var searchBox = this;
|
205
|
+
this.timeout = setTimeout(function (event) {
|
206
|
+
searchBox._onSearch(event);
|
207
|
+
},
|
208
|
+
this.delay);
|
209
|
+
};
|
210
|
+
|
211
|
+
/**
|
212
|
+
* Handle onSearch event
|
213
|
+
* @param {Event} event
|
214
|
+
* @param {boolean} [forceSearch] If true, search will be executed again even
|
215
|
+
* when the search text is not changed.
|
216
|
+
* Default is false.
|
217
|
+
* @private
|
218
|
+
*/
|
219
|
+
SearchBox.prototype._onSearch = function (event, forceSearch) {
|
220
|
+
this._clearDelay();
|
221
|
+
|
222
|
+
var value = this.dom.search.value;
|
223
|
+
var text = (value.length > 0) ? value : undefined;
|
224
|
+
if (text != this.lastText || forceSearch) {
|
225
|
+
// only search again when changed
|
226
|
+
this.lastText = text;
|
227
|
+
this.results = this.editor.search(text);
|
228
|
+
this._setActiveResult(undefined);
|
229
|
+
|
230
|
+
// display search results
|
231
|
+
if (text != undefined) {
|
232
|
+
var resultCount = this.results.length;
|
233
|
+
switch (resultCount) {
|
234
|
+
case 0: this.dom.results.innerHTML = 'no results'; break;
|
235
|
+
case 1: this.dom.results.innerHTML = '1 result'; break;
|
236
|
+
default: this.dom.results.innerHTML = resultCount + ' results'; break;
|
237
|
+
}
|
238
|
+
}
|
239
|
+
else {
|
240
|
+
this.dom.results.innerHTML = '';
|
241
|
+
}
|
242
|
+
}
|
243
|
+
};
|
244
|
+
|
245
|
+
/**
|
246
|
+
* Handle onKeyDown event in the input box
|
247
|
+
* @param {Event} event
|
248
|
+
* @private
|
249
|
+
*/
|
250
|
+
SearchBox.prototype._onKeyDown = function (event) {
|
251
|
+
event = event || window.event;
|
252
|
+
var keynum = event.which || event.keyCode;
|
253
|
+
if (keynum == 27) { // ESC
|
254
|
+
this.dom.search.value = ''; // clear search
|
255
|
+
this._onSearch(event);
|
256
|
+
util.preventDefault(event);
|
257
|
+
util.stopPropagation(event);
|
258
|
+
}
|
259
|
+
else if (keynum == 13) { // Enter
|
260
|
+
if (event.ctrlKey) {
|
261
|
+
// force to search again
|
262
|
+
this._onSearch(event, true);
|
263
|
+
}
|
264
|
+
else if (event.shiftKey) {
|
265
|
+
// move to the previous search result
|
266
|
+
this.previous();
|
267
|
+
}
|
268
|
+
else {
|
269
|
+
// move to the next search result
|
270
|
+
this.next();
|
271
|
+
}
|
272
|
+
util.preventDefault(event);
|
273
|
+
util.stopPropagation(event);
|
274
|
+
}
|
275
|
+
};
|
276
|
+
|
277
|
+
/**
|
278
|
+
* Handle onKeyUp event in the input box
|
279
|
+
* @param {Event} event
|
280
|
+
* @private
|
281
|
+
*/
|
282
|
+
SearchBox.prototype._onKeyUp = function (event) {
|
283
|
+
event = event || window.event;
|
284
|
+
var keynum = event.which || event.keyCode;
|
285
|
+
if (keynum != 27 && keynum != 13) { // !show and !Enter
|
286
|
+
this._onDelayedSearch(event); // For IE 8
|
287
|
+
}
|
288
|
+
};
|
@@ -0,0 +1,311 @@
|
|
1
|
+
/**
|
2
|
+
* Create a TextEditor and attach it to given container
|
3
|
+
* @constructor TextEditor
|
4
|
+
* @param {Element} container
|
5
|
+
* @param {Object} [options] Object with options. available options:
|
6
|
+
* {String} mode Available values:
|
7
|
+
* "text" (default)
|
8
|
+
* or "code".
|
9
|
+
* {Number} indentation Number of indentation
|
10
|
+
* spaces. 4 by default.
|
11
|
+
* {function} change Callback method
|
12
|
+
* triggered on change
|
13
|
+
* @param {JSON | String} [json] initial contents of the formatter
|
14
|
+
*/
|
15
|
+
function TextEditor(container, options, json) {
|
16
|
+
if (!(this instanceof TextEditor)) {
|
17
|
+
throw new Error('TextEditor constructor called without "new".');
|
18
|
+
}
|
19
|
+
|
20
|
+
this._create(container, options, json);
|
21
|
+
}
|
22
|
+
|
23
|
+
/**
|
24
|
+
* Create a TextEditor and attach it to given container
|
25
|
+
* @constructor TextEditor
|
26
|
+
* @param {Element} container
|
27
|
+
* @param {Object} [options] See description in constructor
|
28
|
+
* @param {JSON | String} [json] initial contents of the formatter
|
29
|
+
* @private
|
30
|
+
*/
|
31
|
+
TextEditor.prototype._create = function (container, options, json) {
|
32
|
+
// check availability of JSON parser (not available in IE7 and older)
|
33
|
+
if (typeof(JSON) == 'undefined') {
|
34
|
+
throw new Error('Your browser does not support JSON. \n\n' +
|
35
|
+
'Please install the newest version of your browser.\n' +
|
36
|
+
'(all modern browsers support JSON).');
|
37
|
+
}
|
38
|
+
|
39
|
+
// read options
|
40
|
+
options = options || {};
|
41
|
+
if (options.indentation) {
|
42
|
+
this.indentation = Number(options.indentation);
|
43
|
+
}
|
44
|
+
this.options = options;
|
45
|
+
this.mode = (options.mode == 'code') ? 'code' : 'text';
|
46
|
+
if (this.mode == 'code') {
|
47
|
+
// verify whether Ace editor is available and supported
|
48
|
+
if (typeof ace === 'undefined') {
|
49
|
+
this.mode = 'text';
|
50
|
+
util.log('WARNING: Cannot load code editor, Ace library not loaded. ' +
|
51
|
+
'Falling back to plain text editor');
|
52
|
+
}
|
53
|
+
if (util.getInternetExplorerVersion() == 8) {
|
54
|
+
this.mode = 'text';
|
55
|
+
util.log('WARNING: Cannot load code editor, Ace is not supported on IE8. ' +
|
56
|
+
'Falling back to plain text editor');
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
var me = this;
|
61
|
+
this.container = container;
|
62
|
+
this.editor = undefined; // ace code editor
|
63
|
+
this.textarea = undefined; // plain text editor (fallback when Ace is not available)
|
64
|
+
this.indentation = 4; // number of spaces
|
65
|
+
|
66
|
+
this.width = container.clientWidth;
|
67
|
+
this.height = container.clientHeight;
|
68
|
+
|
69
|
+
this.frame = document.createElement('div');
|
70
|
+
this.frame.className = 'jsoneditor';
|
71
|
+
this.frame.onclick = function (event) {
|
72
|
+
// prevent default submit action when TextEditor is located inside a form
|
73
|
+
util.preventDefault(event);
|
74
|
+
};
|
75
|
+
|
76
|
+
// create menu
|
77
|
+
this.menu = document.createElement('div');
|
78
|
+
this.menu.className = 'menu';
|
79
|
+
this.frame.appendChild(this.menu);
|
80
|
+
|
81
|
+
// create format button
|
82
|
+
var buttonFormat = document.createElement('button');
|
83
|
+
//buttonFormat.innerHTML = 'Format';
|
84
|
+
buttonFormat.className = 'format';
|
85
|
+
buttonFormat.title = 'Format JSON data, with proper indentation and line feeds';
|
86
|
+
//buttonFormat.className = 'jsoneditor-button';
|
87
|
+
this.menu.appendChild(buttonFormat);
|
88
|
+
buttonFormat.onclick = function () {
|
89
|
+
try {
|
90
|
+
me.format();
|
91
|
+
}
|
92
|
+
catch (err) {
|
93
|
+
me._onError(err);
|
94
|
+
}
|
95
|
+
};
|
96
|
+
|
97
|
+
// create compact button
|
98
|
+
var buttonCompact = document.createElement('button');
|
99
|
+
//buttonCompact.innerHTML = 'Compact';
|
100
|
+
buttonCompact.className = 'compact';
|
101
|
+
buttonCompact.title = 'Compact JSON data, remove all whitespaces';
|
102
|
+
//buttonCompact.className = 'jsoneditor-button';
|
103
|
+
this.menu.appendChild(buttonCompact);
|
104
|
+
buttonCompact.onclick = function () {
|
105
|
+
try {
|
106
|
+
me.compact();
|
107
|
+
}
|
108
|
+
catch (err) {
|
109
|
+
me._onError(err);
|
110
|
+
}
|
111
|
+
|
112
|
+
};
|
113
|
+
|
114
|
+
this.content = document.createElement('div');
|
115
|
+
this.content.className = 'outer';
|
116
|
+
this.frame.appendChild(this.content);
|
117
|
+
|
118
|
+
this.container.appendChild(this.frame);
|
119
|
+
|
120
|
+
if (this.mode == 'code') {
|
121
|
+
this.editorDom = document.createElement('div');
|
122
|
+
this.editorDom.style.height = '100%'; // TODO: move to css
|
123
|
+
this.editorDom.style.width = '100%'; // TODO: move to css
|
124
|
+
this.content.appendChild(this.editorDom);
|
125
|
+
|
126
|
+
var editor = ace.edit(this.editorDom);
|
127
|
+
editor.setTheme('ace/theme/jsoneditor');
|
128
|
+
editor.setShowPrintMargin(false);
|
129
|
+
editor.setFontSize(13);
|
130
|
+
editor.getSession().setMode('ace/mode/json');
|
131
|
+
editor.getSession().setUseSoftTabs(true);
|
132
|
+
editor.getSession().setUseWrapMode(true);
|
133
|
+
this.editor = editor;
|
134
|
+
|
135
|
+
var poweredBy = document.createElement('a');
|
136
|
+
poweredBy.appendChild(document.createTextNode('powered by ace'));
|
137
|
+
poweredBy.href = 'http://ace.ajax.org';
|
138
|
+
poweredBy.target = '_blank';
|
139
|
+
poweredBy.className = 'poweredBy';
|
140
|
+
poweredBy.onclick = function () {
|
141
|
+
// TODO: this anchor falls below the margin of the content,
|
142
|
+
// therefore the normal a.href does not work. We use a click event
|
143
|
+
// for now, but this should be fixed.
|
144
|
+
window.open(poweredBy.href, poweredBy.target);
|
145
|
+
};
|
146
|
+
this.menu.appendChild(poweredBy);
|
147
|
+
|
148
|
+
if (options.change) {
|
149
|
+
// register onchange event
|
150
|
+
editor.on('change', function () {
|
151
|
+
options.change();
|
152
|
+
});
|
153
|
+
}
|
154
|
+
}
|
155
|
+
else {
|
156
|
+
// load a plain text textarea
|
157
|
+
var textarea = document.createElement('textarea');
|
158
|
+
textarea.className = 'content';
|
159
|
+
textarea.spellcheck = false;
|
160
|
+
this.content.appendChild(textarea);
|
161
|
+
this.textarea = textarea;
|
162
|
+
|
163
|
+
if (options.change) {
|
164
|
+
// register onchange event
|
165
|
+
if (this.textarea.oninput === null) {
|
166
|
+
this.textarea.oninput = function () {
|
167
|
+
options.change();
|
168
|
+
}
|
169
|
+
}
|
170
|
+
else {
|
171
|
+
// oninput is undefined. For IE8-
|
172
|
+
this.textarea.onchange = function () {
|
173
|
+
options.change();
|
174
|
+
}
|
175
|
+
}
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
// load initial json object or string
|
180
|
+
if (typeof(json) == 'string') {
|
181
|
+
this.setText(json);
|
182
|
+
}
|
183
|
+
else {
|
184
|
+
this.set(json);
|
185
|
+
}
|
186
|
+
};
|
187
|
+
|
188
|
+
/**
|
189
|
+
* Detach the editor from the DOM
|
190
|
+
* @private
|
191
|
+
*/
|
192
|
+
TextEditor.prototype._delete = function () {
|
193
|
+
if (this.frame && this.container && this.frame.parentNode == this.container) {
|
194
|
+
this.container.removeChild(this.frame);
|
195
|
+
}
|
196
|
+
};
|
197
|
+
|
198
|
+
/**
|
199
|
+
* Throw an error. If an error callback is configured in options.error, this
|
200
|
+
* callback will be invoked. Else, a regular error is thrown.
|
201
|
+
* @param {Error} err
|
202
|
+
* @private
|
203
|
+
*/
|
204
|
+
TextEditor.prototype._onError = function(err) {
|
205
|
+
// TODO: onError is deprecated since version 2.2.0. cleanup some day
|
206
|
+
if (typeof this.onError === 'function') {
|
207
|
+
util.log('WARNING: JSONEditor.onError is deprecated. ' +
|
208
|
+
'Use options.error instead.');
|
209
|
+
this.onError(err);
|
210
|
+
}
|
211
|
+
|
212
|
+
if (typeof this.options.error === 'function') {
|
213
|
+
this.options.error(err);
|
214
|
+
}
|
215
|
+
else {
|
216
|
+
throw err;
|
217
|
+
}
|
218
|
+
};
|
219
|
+
|
220
|
+
/**
|
221
|
+
* Compact the code in the formatter
|
222
|
+
*/
|
223
|
+
TextEditor.prototype.compact = function () {
|
224
|
+
var json = util.parse(this.getText());
|
225
|
+
this.setText(JSON.stringify(json));
|
226
|
+
};
|
227
|
+
|
228
|
+
/**
|
229
|
+
* Format the code in the formatter
|
230
|
+
*/
|
231
|
+
TextEditor.prototype.format = function () {
|
232
|
+
var json = util.parse(this.getText());
|
233
|
+
this.setText(JSON.stringify(json, null, this.indentation));
|
234
|
+
};
|
235
|
+
|
236
|
+
/**
|
237
|
+
* Set focus to the formatter
|
238
|
+
*/
|
239
|
+
TextEditor.prototype.focus = function () {
|
240
|
+
if (this.textarea) {
|
241
|
+
this.textarea.focus();
|
242
|
+
}
|
243
|
+
if (this.editor) {
|
244
|
+
this.editor.focus();
|
245
|
+
}
|
246
|
+
};
|
247
|
+
|
248
|
+
/**
|
249
|
+
* Resize the formatter
|
250
|
+
*/
|
251
|
+
TextEditor.prototype.resize = function () {
|
252
|
+
if (this.editor) {
|
253
|
+
var force = false;
|
254
|
+
this.editor.resize(force);
|
255
|
+
}
|
256
|
+
};
|
257
|
+
|
258
|
+
/**
|
259
|
+
* Set json data in the formatter
|
260
|
+
* @param {Object} json
|
261
|
+
*/
|
262
|
+
TextEditor.prototype.set = function(json) {
|
263
|
+
this.setText(JSON.stringify(json, null, this.indentation));
|
264
|
+
};
|
265
|
+
|
266
|
+
/**
|
267
|
+
* Get json data from the formatter
|
268
|
+
* @return {Object} json
|
269
|
+
*/
|
270
|
+
TextEditor.prototype.get = function() {
|
271
|
+
return util.parse(this.getText());
|
272
|
+
};
|
273
|
+
|
274
|
+
/**
|
275
|
+
* Get the text contents of the TextEditor
|
276
|
+
* @return {String} jsonText
|
277
|
+
*/
|
278
|
+
TextEditor.prototype.getText = function() {
|
279
|
+
if (this.textarea) {
|
280
|
+
return this.textarea.value;
|
281
|
+
}
|
282
|
+
if (this.editor) {
|
283
|
+
return this.editor.getValue();
|
284
|
+
}
|
285
|
+
return '';
|
286
|
+
};
|
287
|
+
|
288
|
+
/**
|
289
|
+
* Set the text contents of the TextEditor
|
290
|
+
* @param {String} jsonText
|
291
|
+
*/
|
292
|
+
TextEditor.prototype.setText = function(jsonText) {
|
293
|
+
if (this.textarea) {
|
294
|
+
this.textarea.value = jsonText;
|
295
|
+
}
|
296
|
+
if (this.editor) {
|
297
|
+
this.editor.setValue(jsonText, -1);
|
298
|
+
}
|
299
|
+
};
|
300
|
+
|
301
|
+
// register modes at the JSONEditor
|
302
|
+
JSONEditor.modes.text = {
|
303
|
+
editor: TextEditor,
|
304
|
+
data: 'text',
|
305
|
+
load: TextEditor.prototype.format
|
306
|
+
};
|
307
|
+
JSONEditor.modes.code = {
|
308
|
+
editor: TextEditor,
|
309
|
+
data: 'text',
|
310
|
+
load: TextEditor.prototype.format
|
311
|
+
};
|