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,582 @@
|
|
1
|
+
// create namespace
|
2
|
+
util = {};
|
3
|
+
|
4
|
+
// Internet Explorer 8 and older does not support Array.indexOf,
|
5
|
+
// so we define it here in that case
|
6
|
+
// http://soledadpenades.com/2007/05/17/arrayindexof-in-internet-explorer/
|
7
|
+
if(!Array.prototype.indexOf) {
|
8
|
+
Array.prototype.indexOf = function(obj){
|
9
|
+
for(var i = 0; i < this.length; i++){
|
10
|
+
if(this[i] == obj){
|
11
|
+
return i;
|
12
|
+
}
|
13
|
+
}
|
14
|
+
return -1;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
// Internet Explorer 8 and older does not support Array.forEach,
|
19
|
+
// so we define it here in that case
|
20
|
+
// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach
|
21
|
+
if (!Array.prototype.forEach) {
|
22
|
+
Array.prototype.forEach = function(fn, scope) {
|
23
|
+
for(var i = 0, len = this.length; i < len; ++i) {
|
24
|
+
fn.call(scope || this, this[i], i, this);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
/**
|
30
|
+
* Parse JSON using the parser built-in in the browser.
|
31
|
+
* On exception, the jsonString is validated and a detailed error is thrown.
|
32
|
+
* @param {String} jsonString
|
33
|
+
*/
|
34
|
+
util.parse = function (jsonString) {
|
35
|
+
try {
|
36
|
+
return JSON.parse(jsonString);
|
37
|
+
}
|
38
|
+
catch (err) {
|
39
|
+
// try to throw a more detailed error message using validate
|
40
|
+
util.validate(jsonString);
|
41
|
+
throw err;
|
42
|
+
}
|
43
|
+
};
|
44
|
+
|
45
|
+
/**
|
46
|
+
* Validate a string containing a JSON object
|
47
|
+
* This method uses JSONLint to validate the String. If JSONLint is not
|
48
|
+
* available, the built-in JSON parser of the browser is used.
|
49
|
+
* @param {String} jsonString String with an (invalid) JSON object
|
50
|
+
* @throws Error
|
51
|
+
*/
|
52
|
+
util.validate = function (jsonString) {
|
53
|
+
if (typeof(jsonlint) != 'undefined') {
|
54
|
+
jsonlint.parse(jsonString);
|
55
|
+
}
|
56
|
+
else {
|
57
|
+
JSON.parse(jsonString);
|
58
|
+
}
|
59
|
+
};
|
60
|
+
|
61
|
+
/**
|
62
|
+
* Extend object a with the properties of object b
|
63
|
+
* @param {Object} a
|
64
|
+
* @param {Object} b
|
65
|
+
* @return {Object} a
|
66
|
+
*/
|
67
|
+
util.extend = function (a, b) {
|
68
|
+
for (var prop in b) {
|
69
|
+
if (b.hasOwnProperty(prop)) {
|
70
|
+
a[prop] = b[prop];
|
71
|
+
}
|
72
|
+
}
|
73
|
+
return a;
|
74
|
+
};
|
75
|
+
|
76
|
+
/**
|
77
|
+
* Remove all properties from object a
|
78
|
+
* @param {Object} a
|
79
|
+
* @return {Object} a
|
80
|
+
*/
|
81
|
+
util.clear = function (a) {
|
82
|
+
for (var prop in a) {
|
83
|
+
if (a.hasOwnProperty(prop)) {
|
84
|
+
delete a[prop];
|
85
|
+
}
|
86
|
+
}
|
87
|
+
return a;
|
88
|
+
};
|
89
|
+
|
90
|
+
/**
|
91
|
+
* Output text to the console, if console is available
|
92
|
+
* @param {...*} args
|
93
|
+
*/
|
94
|
+
util.log = function(args) {
|
95
|
+
if (console && typeof console.log === 'function') {
|
96
|
+
console.log.apply(console, arguments);
|
97
|
+
}
|
98
|
+
};
|
99
|
+
|
100
|
+
/**
|
101
|
+
* Test whether a text contains a url (matches when a string starts
|
102
|
+
* with 'http://*' or 'https://*' and has no whitespace characters)
|
103
|
+
* @param {String} text
|
104
|
+
*/
|
105
|
+
var isUrlRegex = /^https?:\/\/\S+$/;
|
106
|
+
util.isUrl = function (text) {
|
107
|
+
return (typeof text == 'string' || text instanceof String) &&
|
108
|
+
isUrlRegex.test(text);
|
109
|
+
};
|
110
|
+
|
111
|
+
/**
|
112
|
+
* Retrieve the absolute left value of a DOM element
|
113
|
+
* @param {Element} elem A dom element, for example a div
|
114
|
+
* @return {Number} left The absolute left position of this element
|
115
|
+
* in the browser page.
|
116
|
+
*/
|
117
|
+
util.getAbsoluteLeft = function (elem) {
|
118
|
+
var left = elem.offsetLeft;
|
119
|
+
var body = document.body;
|
120
|
+
var e = elem.offsetParent;
|
121
|
+
while (e != null && elem != body) {
|
122
|
+
left += e.offsetLeft;
|
123
|
+
left -= e.scrollLeft;
|
124
|
+
e = e.offsetParent;
|
125
|
+
}
|
126
|
+
return left;
|
127
|
+
};
|
128
|
+
|
129
|
+
/**
|
130
|
+
* Retrieve the absolute top value of a DOM element
|
131
|
+
* @param {Element} elem A dom element, for example a div
|
132
|
+
* @return {Number} top The absolute top position of this element
|
133
|
+
* in the browser page.
|
134
|
+
*/
|
135
|
+
util.getAbsoluteTop = function (elem) {
|
136
|
+
var top = elem.offsetTop;
|
137
|
+
var body = document.body;
|
138
|
+
var e = elem.offsetParent;
|
139
|
+
while (e != null && e != body) {
|
140
|
+
top += e.offsetTop;
|
141
|
+
top -= e.scrollTop;
|
142
|
+
e = e.offsetParent;
|
143
|
+
}
|
144
|
+
return top;
|
145
|
+
};
|
146
|
+
|
147
|
+
/**
|
148
|
+
* Get the absolute, vertical mouse position from an event.
|
149
|
+
* @param {Event} event
|
150
|
+
* @return {Number} mouseY
|
151
|
+
*/
|
152
|
+
util.getMouseY = function (event) {
|
153
|
+
var mouseY;
|
154
|
+
if ('pageY' in event) {
|
155
|
+
mouseY = event.pageY;
|
156
|
+
}
|
157
|
+
else {
|
158
|
+
// for IE8 and older
|
159
|
+
mouseY = (event.clientY + document.documentElement.scrollTop);
|
160
|
+
}
|
161
|
+
|
162
|
+
return mouseY;
|
163
|
+
};
|
164
|
+
|
165
|
+
/**
|
166
|
+
* Get the absolute, horizontal mouse position from an event.
|
167
|
+
* @param {Event} event
|
168
|
+
* @return {Number} mouseX
|
169
|
+
*/
|
170
|
+
util.getMouseX = function (event) {
|
171
|
+
var mouseX;
|
172
|
+
if ('pageX' in event) {
|
173
|
+
mouseX = event.pageX;
|
174
|
+
}
|
175
|
+
else {
|
176
|
+
// for IE8 and older
|
177
|
+
mouseX = (event.clientX + document.documentElement.scrollLeft);
|
178
|
+
}
|
179
|
+
|
180
|
+
return mouseX;
|
181
|
+
};
|
182
|
+
|
183
|
+
/**
|
184
|
+
* Get the window height
|
185
|
+
* @return {Number} windowHeight
|
186
|
+
*/
|
187
|
+
util.getWindowHeight = function () {
|
188
|
+
if ('innerHeight' in window) {
|
189
|
+
return window.innerHeight;
|
190
|
+
}
|
191
|
+
else {
|
192
|
+
// for IE8 and older
|
193
|
+
return Math.max(document.body.clientHeight,
|
194
|
+
document.documentElement.clientHeight);
|
195
|
+
}
|
196
|
+
};
|
197
|
+
|
198
|
+
/**
|
199
|
+
* add a className to the given elements style
|
200
|
+
* @param {Element} elem
|
201
|
+
* @param {String} className
|
202
|
+
*/
|
203
|
+
util.addClassName = function(elem, className) {
|
204
|
+
var classes = elem.className.split(' ');
|
205
|
+
if (classes.indexOf(className) == -1) {
|
206
|
+
classes.push(className); // add the class to the array
|
207
|
+
elem.className = classes.join(' ');
|
208
|
+
}
|
209
|
+
};
|
210
|
+
|
211
|
+
/**
|
212
|
+
* add a className to the given elements style
|
213
|
+
* @param {Element} elem
|
214
|
+
* @param {String} className
|
215
|
+
*/
|
216
|
+
util.removeClassName = function(elem, className) {
|
217
|
+
var classes = elem.className.split(' ');
|
218
|
+
var index = classes.indexOf(className);
|
219
|
+
if (index != -1) {
|
220
|
+
classes.splice(index, 1); // remove the class from the array
|
221
|
+
elem.className = classes.join(' ');
|
222
|
+
}
|
223
|
+
};
|
224
|
+
|
225
|
+
/**
|
226
|
+
* Strip the formatting from the contents of a div
|
227
|
+
* the formatting from the div itself is not stripped, only from its childs.
|
228
|
+
* @param {Element} divElement
|
229
|
+
*/
|
230
|
+
util.stripFormatting = function (divElement) {
|
231
|
+
var childs = divElement.childNodes;
|
232
|
+
for (var i = 0, iMax = childs.length; i < iMax; i++) {
|
233
|
+
var child = childs[i];
|
234
|
+
|
235
|
+
// remove the style
|
236
|
+
if (child.style) {
|
237
|
+
// TODO: test if child.attributes does contain style
|
238
|
+
child.removeAttribute('style');
|
239
|
+
}
|
240
|
+
|
241
|
+
// remove all attributes
|
242
|
+
var attributes = child.attributes;
|
243
|
+
if (attributes) {
|
244
|
+
for (var j = attributes.length - 1; j >= 0; j--) {
|
245
|
+
var attribute = attributes[j];
|
246
|
+
if (attribute.specified == true) {
|
247
|
+
child.removeAttribute(attribute.name);
|
248
|
+
}
|
249
|
+
}
|
250
|
+
}
|
251
|
+
|
252
|
+
// recursively strip childs
|
253
|
+
util.stripFormatting(child);
|
254
|
+
}
|
255
|
+
};
|
256
|
+
|
257
|
+
/**
|
258
|
+
* Set focus to the end of an editable div
|
259
|
+
* code from Nico Burns
|
260
|
+
* http://stackoverflow.com/users/140293/nico-burns
|
261
|
+
* http://stackoverflow.com/questions/1125292/how-to-move-cursor-to-end-of-contenteditable-entity
|
262
|
+
* @param {Element} contentEditableElement A content editable div
|
263
|
+
*/
|
264
|
+
util.setEndOfContentEditable = function (contentEditableElement) {
|
265
|
+
var range, selection;
|
266
|
+
if(document.createRange) {//Firefox, Chrome, Opera, Safari, IE 9+
|
267
|
+
range = document.createRange();//Create a range (a range is a like the selection but invisible)
|
268
|
+
range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
|
269
|
+
range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
|
270
|
+
selection = window.getSelection();//get the selection object (allows you to change selection)
|
271
|
+
selection.removeAllRanges();//remove any selections already made
|
272
|
+
selection.addRange(range);//make the range you have just created the visible selection
|
273
|
+
}
|
274
|
+
else if(document.selection) {//IE 8 and lower
|
275
|
+
range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
|
276
|
+
range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
|
277
|
+
range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
|
278
|
+
range.select();//Select the range (make it the visible selection
|
279
|
+
}
|
280
|
+
};
|
281
|
+
|
282
|
+
/**
|
283
|
+
* Select all text of a content editable div.
|
284
|
+
* http://stackoverflow.com/a/3806004/1262753
|
285
|
+
* @param {Element} contentEditableElement A content editable div
|
286
|
+
*/
|
287
|
+
util.selectContentEditable = function (contentEditableElement) {
|
288
|
+
if (!contentEditableElement || contentEditableElement.nodeName != 'DIV') {
|
289
|
+
return;
|
290
|
+
}
|
291
|
+
|
292
|
+
var sel, range;
|
293
|
+
if (window.getSelection && document.createRange) {
|
294
|
+
range = document.createRange();
|
295
|
+
range.selectNodeContents(contentEditableElement);
|
296
|
+
sel = window.getSelection();
|
297
|
+
sel.removeAllRanges();
|
298
|
+
sel.addRange(range);
|
299
|
+
} else if (document.body.createTextRange) {
|
300
|
+
range = document.body.createTextRange();
|
301
|
+
range.moveToElementText(contentEditableElement);
|
302
|
+
range.select();
|
303
|
+
}
|
304
|
+
};
|
305
|
+
|
306
|
+
/**
|
307
|
+
* Get text selection
|
308
|
+
* http://stackoverflow.com/questions/4687808/contenteditable-selected-text-save-and-restore
|
309
|
+
* @return {Range | TextRange | null} range
|
310
|
+
*/
|
311
|
+
util.getSelection = function () {
|
312
|
+
if (window.getSelection) {
|
313
|
+
var sel = window.getSelection();
|
314
|
+
if (sel.getRangeAt && sel.rangeCount) {
|
315
|
+
return sel.getRangeAt(0);
|
316
|
+
}
|
317
|
+
} else if (document.selection && document.selection.createRange) {
|
318
|
+
return document.selection.createRange();
|
319
|
+
}
|
320
|
+
return null;
|
321
|
+
};
|
322
|
+
|
323
|
+
/**
|
324
|
+
* Set text selection
|
325
|
+
* http://stackoverflow.com/questions/4687808/contenteditable-selected-text-save-and-restore
|
326
|
+
* @param {Range | TextRange | null} range
|
327
|
+
*/
|
328
|
+
util.setSelection = function (range) {
|
329
|
+
if (range) {
|
330
|
+
if (window.getSelection) {
|
331
|
+
var sel = window.getSelection();
|
332
|
+
sel.removeAllRanges();
|
333
|
+
sel.addRange(range);
|
334
|
+
} else if (document.selection && range.select) {
|
335
|
+
range.select();
|
336
|
+
}
|
337
|
+
}
|
338
|
+
};
|
339
|
+
|
340
|
+
/**
|
341
|
+
* Get selected text range
|
342
|
+
* @return {Object} params object containing parameters:
|
343
|
+
* {Number} startOffset
|
344
|
+
* {Number} endOffset
|
345
|
+
* {Element} container HTML element holding the
|
346
|
+
* selected text element
|
347
|
+
* Returns null if no text selection is found
|
348
|
+
*/
|
349
|
+
util.getSelectionOffset = function () {
|
350
|
+
var range = util.getSelection();
|
351
|
+
|
352
|
+
if (range && 'startOffset' in range && 'endOffset' in range &&
|
353
|
+
range.startContainer && (range.startContainer == range.endContainer)) {
|
354
|
+
return {
|
355
|
+
startOffset: range.startOffset,
|
356
|
+
endOffset: range.endOffset,
|
357
|
+
container: range.startContainer.parentNode
|
358
|
+
};
|
359
|
+
}
|
360
|
+
else {
|
361
|
+
// TODO: implement getSelectionOffset for IE8
|
362
|
+
}
|
363
|
+
|
364
|
+
return null;
|
365
|
+
};
|
366
|
+
|
367
|
+
/**
|
368
|
+
* Set selected text range in given element
|
369
|
+
* @param {Object} params An object containing:
|
370
|
+
* {Element} container
|
371
|
+
* {Number} startOffset
|
372
|
+
* {Number} endOffset
|
373
|
+
*/
|
374
|
+
util.setSelectionOffset = function (params) {
|
375
|
+
if (document.createRange && window.getSelection) {
|
376
|
+
var selection = window.getSelection();
|
377
|
+
if(selection) {
|
378
|
+
var range = document.createRange();
|
379
|
+
// TODO: do not suppose that the first child of the container is a textnode,
|
380
|
+
// but recursively find the textnodes
|
381
|
+
range.setStart(params.container.firstChild, params.startOffset);
|
382
|
+
range.setEnd(params.container.firstChild, params.endOffset);
|
383
|
+
|
384
|
+
util.setSelection(range);
|
385
|
+
}
|
386
|
+
}
|
387
|
+
else {
|
388
|
+
// TODO: implement setSelectionOffset for IE8
|
389
|
+
}
|
390
|
+
};
|
391
|
+
|
392
|
+
/**
|
393
|
+
* Get the inner text of an HTML element (for example a div element)
|
394
|
+
* @param {Element} element
|
395
|
+
* @param {Object} [buffer]
|
396
|
+
* @return {String} innerText
|
397
|
+
*/
|
398
|
+
util.getInnerText = function (element, buffer) {
|
399
|
+
var first = (buffer == undefined);
|
400
|
+
if (first) {
|
401
|
+
buffer = {
|
402
|
+
'text': '',
|
403
|
+
'flush': function () {
|
404
|
+
var text = this.text;
|
405
|
+
this.text = '';
|
406
|
+
return text;
|
407
|
+
},
|
408
|
+
'set': function (text) {
|
409
|
+
this.text = text;
|
410
|
+
}
|
411
|
+
};
|
412
|
+
}
|
413
|
+
|
414
|
+
// text node
|
415
|
+
if (element.nodeValue) {
|
416
|
+
return buffer.flush() + element.nodeValue;
|
417
|
+
}
|
418
|
+
|
419
|
+
// divs or other HTML elements
|
420
|
+
if (element.hasChildNodes()) {
|
421
|
+
var childNodes = element.childNodes;
|
422
|
+
var innerText = '';
|
423
|
+
|
424
|
+
for (var i = 0, iMax = childNodes.length; i < iMax; i++) {
|
425
|
+
var child = childNodes[i];
|
426
|
+
|
427
|
+
if (child.nodeName == 'DIV' || child.nodeName == 'P') {
|
428
|
+
var prevChild = childNodes[i - 1];
|
429
|
+
var prevName = prevChild ? prevChild.nodeName : undefined;
|
430
|
+
if (prevName && prevName != 'DIV' && prevName != 'P' && prevName != 'BR') {
|
431
|
+
innerText += '\n';
|
432
|
+
buffer.flush();
|
433
|
+
}
|
434
|
+
innerText += util.getInnerText(child, buffer);
|
435
|
+
buffer.set('\n');
|
436
|
+
}
|
437
|
+
else if (child.nodeName == 'BR') {
|
438
|
+
innerText += buffer.flush();
|
439
|
+
buffer.set('\n');
|
440
|
+
}
|
441
|
+
else {
|
442
|
+
innerText += util.getInnerText(child, buffer);
|
443
|
+
}
|
444
|
+
}
|
445
|
+
|
446
|
+
return innerText;
|
447
|
+
}
|
448
|
+
else {
|
449
|
+
if (element.nodeName == 'P' && util.getInternetExplorerVersion() != -1) {
|
450
|
+
// On Internet Explorer, a <p> with hasChildNodes()==false is
|
451
|
+
// rendered with a new line. Note that a <p> with
|
452
|
+
// hasChildNodes()==true is rendered without a new line
|
453
|
+
// Other browsers always ensure there is a <br> inside the <p>,
|
454
|
+
// and if not, the <p> does not render a new line
|
455
|
+
return buffer.flush();
|
456
|
+
}
|
457
|
+
}
|
458
|
+
|
459
|
+
// br or unknown
|
460
|
+
return '';
|
461
|
+
};
|
462
|
+
|
463
|
+
/**
|
464
|
+
* Returns the version of Internet Explorer or a -1
|
465
|
+
* (indicating the use of another browser).
|
466
|
+
* Source: http://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx
|
467
|
+
* @return {Number} Internet Explorer version, or -1 in case of an other browser
|
468
|
+
*/
|
469
|
+
util.getInternetExplorerVersion = function() {
|
470
|
+
if (_ieVersion == -1) {
|
471
|
+
var rv = -1; // Return value assumes failure.
|
472
|
+
if (navigator.appName == 'Microsoft Internet Explorer')
|
473
|
+
{
|
474
|
+
var ua = navigator.userAgent;
|
475
|
+
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
|
476
|
+
if (re.exec(ua) != null) {
|
477
|
+
rv = parseFloat( RegExp.$1 );
|
478
|
+
}
|
479
|
+
}
|
480
|
+
|
481
|
+
_ieVersion = rv;
|
482
|
+
}
|
483
|
+
|
484
|
+
return _ieVersion;
|
485
|
+
};
|
486
|
+
|
487
|
+
/**
|
488
|
+
* cached internet explorer version
|
489
|
+
* @type {Number}
|
490
|
+
* @private
|
491
|
+
*/
|
492
|
+
var _ieVersion = -1;
|
493
|
+
|
494
|
+
/**
|
495
|
+
* Add and event listener. Works for all browsers
|
496
|
+
* @param {Element} element An html element
|
497
|
+
* @param {string} action The action, for example "click",
|
498
|
+
* without the prefix "on"
|
499
|
+
* @param {function} listener The callback function to be executed
|
500
|
+
* @param {boolean} [useCapture] false by default
|
501
|
+
* @return {function} the created event listener
|
502
|
+
*/
|
503
|
+
util.addEventListener = function (element, action, listener, useCapture) {
|
504
|
+
if (element.addEventListener) {
|
505
|
+
if (useCapture === undefined)
|
506
|
+
useCapture = false;
|
507
|
+
|
508
|
+
if (action === "mousewheel" && navigator.userAgent.indexOf("Firefox") >= 0) {
|
509
|
+
action = "DOMMouseScroll"; // For Firefox
|
510
|
+
}
|
511
|
+
|
512
|
+
element.addEventListener(action, listener, useCapture);
|
513
|
+
return listener;
|
514
|
+
} else {
|
515
|
+
// IE browsers
|
516
|
+
var f = function () {
|
517
|
+
return listener.call(element, window.event);
|
518
|
+
};
|
519
|
+
element.attachEvent("on" + action, f);
|
520
|
+
return f;
|
521
|
+
}
|
522
|
+
};
|
523
|
+
|
524
|
+
/**
|
525
|
+
* Remove an event listener from an element
|
526
|
+
* @param {Element} element An html dom element
|
527
|
+
* @param {string} action The name of the event, for example "mousedown"
|
528
|
+
* @param {function} listener The listener function
|
529
|
+
* @param {boolean} [useCapture] false by default
|
530
|
+
*/
|
531
|
+
util.removeEventListener = function(element, action, listener, useCapture) {
|
532
|
+
if (element.removeEventListener) {
|
533
|
+
// non-IE browsers
|
534
|
+
if (useCapture === undefined)
|
535
|
+
useCapture = false;
|
536
|
+
|
537
|
+
if (action === "mousewheel" && navigator.userAgent.indexOf("Firefox") >= 0) {
|
538
|
+
action = "DOMMouseScroll"; // For Firefox
|
539
|
+
}
|
540
|
+
|
541
|
+
element.removeEventListener(action, listener, useCapture);
|
542
|
+
} else {
|
543
|
+
// IE browsers
|
544
|
+
element.detachEvent("on" + action, listener);
|
545
|
+
}
|
546
|
+
};
|
547
|
+
|
548
|
+
|
549
|
+
/**
|
550
|
+
* Stop event propagation
|
551
|
+
* @param {Event} event
|
552
|
+
*/
|
553
|
+
util.stopPropagation = function (event) {
|
554
|
+
if (!event) {
|
555
|
+
event = window.event;
|
556
|
+
}
|
557
|
+
|
558
|
+
if (event.stopPropagation) {
|
559
|
+
event.stopPropagation(); // non-IE browsers
|
560
|
+
}
|
561
|
+
else {
|
562
|
+
event.cancelBubble = true; // IE browsers
|
563
|
+
}
|
564
|
+
};
|
565
|
+
|
566
|
+
|
567
|
+
/**
|
568
|
+
* Cancels the event if it is cancelable, without stopping further propagation of the event.
|
569
|
+
* @param {Event} event
|
570
|
+
*/
|
571
|
+
util.preventDefault = function (event) {
|
572
|
+
if (!event) {
|
573
|
+
event = window.event;
|
574
|
+
}
|
575
|
+
|
576
|
+
if (event.preventDefault) {
|
577
|
+
event.preventDefault(); // non-IE browsers
|
578
|
+
}
|
579
|
+
else {
|
580
|
+
event.returnValue = false; // IE browsers
|
581
|
+
}
|
582
|
+
};
|