blogelator 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,333 @@
1
+ CodeMirror.defineMode("xml", function(config, parserConfig) {
2
+ var indentUnit = config.indentUnit;
3
+ var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
4
+ var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag;
5
+ if (multilineTagIndentPastTag == null) multilineTagIndentPastTag = true;
6
+
7
+ var Kludges = parserConfig.htmlMode ? {
8
+ autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
9
+ 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
10
+ 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
11
+ 'track': true, 'wbr': true},
12
+ implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
13
+ 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
14
+ 'th': true, 'tr': true},
15
+ contextGrabbers: {
16
+ 'dd': {'dd': true, 'dt': true},
17
+ 'dt': {'dd': true, 'dt': true},
18
+ 'li': {'li': true},
19
+ 'option': {'option': true, 'optgroup': true},
20
+ 'optgroup': {'optgroup': true},
21
+ 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
22
+ 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
23
+ 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
24
+ 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
25
+ 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
26
+ 'rp': {'rp': true, 'rt': true},
27
+ 'rt': {'rp': true, 'rt': true},
28
+ 'tbody': {'tbody': true, 'tfoot': true},
29
+ 'td': {'td': true, 'th': true},
30
+ 'tfoot': {'tbody': true},
31
+ 'th': {'td': true, 'th': true},
32
+ 'thead': {'tbody': true, 'tfoot': true},
33
+ 'tr': {'tr': true}
34
+ },
35
+ doNotIndent: {"pre": true},
36
+ allowUnquoted: true,
37
+ allowMissing: true
38
+ } : {
39
+ autoSelfClosers: {},
40
+ implicitlyClosed: {},
41
+ contextGrabbers: {},
42
+ doNotIndent: {},
43
+ allowUnquoted: false,
44
+ allowMissing: false
45
+ };
46
+ var alignCDATA = parserConfig.alignCDATA;
47
+
48
+ // Return variables for tokenizers
49
+ var tagName, type, setStyle;
50
+
51
+ function inText(stream, state) {
52
+ function chain(parser) {
53
+ state.tokenize = parser;
54
+ return parser(stream, state);
55
+ }
56
+
57
+ var ch = stream.next();
58
+ if (ch == "<") {
59
+ if (stream.eat("!")) {
60
+ if (stream.eat("[")) {
61
+ if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
62
+ else return null;
63
+ } else if (stream.match("--")) {
64
+ return chain(inBlock("comment", "-->"));
65
+ } else if (stream.match("DOCTYPE", true, true)) {
66
+ stream.eatWhile(/[\w\._\-]/);
67
+ return chain(doctype(1));
68
+ } else {
69
+ return null;
70
+ }
71
+ } else if (stream.eat("?")) {
72
+ stream.eatWhile(/[\w\._\-]/);
73
+ state.tokenize = inBlock("meta", "?>");
74
+ return "meta";
75
+ } else {
76
+ var isClose = stream.eat("/");
77
+ tagName = "";
78
+ var c;
79
+ while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
80
+ if (!tagName) return "tag error";
81
+ type = isClose ? "closeTag" : "openTag";
82
+ state.tokenize = inTag;
83
+ return "tag";
84
+ }
85
+ } else if (ch == "&") {
86
+ var ok;
87
+ if (stream.eat("#")) {
88
+ if (stream.eat("x")) {
89
+ ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
90
+ } else {
91
+ ok = stream.eatWhile(/[\d]/) && stream.eat(";");
92
+ }
93
+ } else {
94
+ ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
95
+ }
96
+ return ok ? "atom" : "error";
97
+ } else {
98
+ stream.eatWhile(/[^&<]/);
99
+ return null;
100
+ }
101
+ }
102
+
103
+ function inTag(stream, state) {
104
+ var ch = stream.next();
105
+ if (ch == ">" || (ch == "/" && stream.eat(">"))) {
106
+ state.tokenize = inText;
107
+ type = ch == ">" ? "endTag" : "selfcloseTag";
108
+ return "tag";
109
+ } else if (ch == "=") {
110
+ type = "equals";
111
+ return null;
112
+ } else if (ch == "<") {
113
+ state.tokenize = inText;
114
+ state.state = baseState;
115
+ state.tagName = state.tagStart = null;
116
+ var next = state.tokenize(stream, state);
117
+ return next ? next + " error" : "error";
118
+ } else if (/[\'\"]/.test(ch)) {
119
+ state.tokenize = inAttribute(ch);
120
+ state.stringStartCol = stream.column();
121
+ return state.tokenize(stream, state);
122
+ } else {
123
+ stream.eatWhile(/[^\s\u00a0=<>\"\']/);
124
+ return "word";
125
+ }
126
+ }
127
+
128
+ function inAttribute(quote) {
129
+ var closure = function(stream, state) {
130
+ while (!stream.eol()) {
131
+ if (stream.next() == quote) {
132
+ state.tokenize = inTag;
133
+ break;
134
+ }
135
+ }
136
+ return "string";
137
+ };
138
+ closure.isInAttribute = true;
139
+ return closure;
140
+ }
141
+
142
+ function inBlock(style, terminator) {
143
+ return function(stream, state) {
144
+ while (!stream.eol()) {
145
+ if (stream.match(terminator)) {
146
+ state.tokenize = inText;
147
+ break;
148
+ }
149
+ stream.next();
150
+ }
151
+ return style;
152
+ };
153
+ }
154
+ function doctype(depth) {
155
+ return function(stream, state) {
156
+ var ch;
157
+ while ((ch = stream.next()) != null) {
158
+ if (ch == "<") {
159
+ state.tokenize = doctype(depth + 1);
160
+ return state.tokenize(stream, state);
161
+ } else if (ch == ">") {
162
+ if (depth == 1) {
163
+ state.tokenize = inText;
164
+ break;
165
+ } else {
166
+ state.tokenize = doctype(depth - 1);
167
+ return state.tokenize(stream, state);
168
+ }
169
+ }
170
+ }
171
+ return "meta";
172
+ };
173
+ }
174
+
175
+ function Context(state, tagName, startOfLine) {
176
+ this.prev = state.context;
177
+ this.tagName = tagName;
178
+ this.indent = state.indented;
179
+ this.startOfLine = startOfLine;
180
+ if (Kludges.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
181
+ this.noIndent = true;
182
+ }
183
+ function popContext(state) {
184
+ if (state.context) state.context = state.context.prev;
185
+ }
186
+ function maybePopContext(state, nextTagName) {
187
+ var parentTagName;
188
+ while (true) {
189
+ if (!state.context) {
190
+ return;
191
+ }
192
+ parentTagName = state.context.tagName.toLowerCase();
193
+ if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
194
+ !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
195
+ return;
196
+ }
197
+ popContext(state);
198
+ }
199
+ }
200
+
201
+ function baseState(type, stream, state) {
202
+ if (type == "openTag") {
203
+ state.tagName = tagName;
204
+ state.tagStart = stream.column();
205
+ return attrState;
206
+ } else if (type == "closeTag") {
207
+ var err = false;
208
+ if (state.context) {
209
+ if (state.context.tagName != tagName) {
210
+ if (Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName.toLowerCase()))
211
+ popContext(state);
212
+ err = !state.context || state.context.tagName != tagName;
213
+ }
214
+ } else {
215
+ err = true;
216
+ }
217
+ if (err) setStyle = "error";
218
+ return err ? closeStateErr : closeState;
219
+ } else {
220
+ return baseState;
221
+ }
222
+ }
223
+ function closeState(type, _stream, state) {
224
+ if (type != "endTag") {
225
+ setStyle = "error";
226
+ return closeState;
227
+ }
228
+ popContext(state);
229
+ return baseState;
230
+ }
231
+ function closeStateErr(type, stream, state) {
232
+ setStyle = "error";
233
+ return closeState(type, stream, state);
234
+ }
235
+
236
+ function attrState(type, _stream, state) {
237
+ if (type == "word") {
238
+ setStyle = "attribute";
239
+ return attrEqState;
240
+ } else if (type == "endTag" || type == "selfcloseTag") {
241
+ var tagName = state.tagName, tagStart = state.tagStart;
242
+ state.tagName = state.tagStart = null;
243
+ if (type == "selfcloseTag" ||
244
+ Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase())) {
245
+ maybePopContext(state, tagName.toLowerCase());
246
+ } else {
247
+ maybePopContext(state, tagName.toLowerCase());
248
+ state.context = new Context(state, tagName, tagStart == state.indented);
249
+ }
250
+ return baseState;
251
+ }
252
+ setStyle = "error";
253
+ return attrState;
254
+ }
255
+ function attrEqState(type, stream, state) {
256
+ if (type == "equals") return attrValueState;
257
+ if (!Kludges.allowMissing) setStyle = "error";
258
+ return attrState(type, stream, state);
259
+ }
260
+ function attrValueState(type, stream, state) {
261
+ if (type == "string") return attrContinuedState;
262
+ if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return attrState;}
263
+ setStyle = "error";
264
+ return attrState(type, stream, state);
265
+ }
266
+ function attrContinuedState(type, stream, state) {
267
+ if (type == "string") return attrContinuedState;
268
+ return attrState(type, stream, state);
269
+ }
270
+
271
+ return {
272
+ startState: function() {
273
+ return {tokenize: inText,
274
+ state: baseState,
275
+ indented: 0,
276
+ tagName: null, tagStart: null,
277
+ context: null};
278
+ },
279
+
280
+ token: function(stream, state) {
281
+ if (!state.tagName && stream.sol())
282
+ state.indented = stream.indentation();
283
+
284
+ if (stream.eatSpace()) return null;
285
+ tagName = type = null;
286
+ var style = state.tokenize(stream, state);
287
+ if ((style || type) && style != "comment") {
288
+ setStyle = null;
289
+ state.state = state.state(type || style, stream, state);
290
+ if (setStyle)
291
+ style = setStyle == "error" ? style + " error" : setStyle;
292
+ }
293
+ return style;
294
+ },
295
+
296
+ indent: function(state, textAfter, fullLine) {
297
+ var context = state.context;
298
+ // Indent multi-line strings (e.g. css).
299
+ if (state.tokenize.isInAttribute) {
300
+ return state.stringStartCol + 1;
301
+ }
302
+ if (context && context.noIndent) return CodeMirror.Pass;
303
+ if (state.tokenize != inTag && state.tokenize != inText)
304
+ return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
305
+ // Indent the starts of attribute names.
306
+ if (state.tagName) {
307
+ if (multilineTagIndentPastTag)
308
+ return state.tagStart + state.tagName.length + 2;
309
+ else
310
+ return state.tagStart + indentUnit * multilineTagIndentFactor;
311
+ }
312
+ if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
313
+ if (context && /^<\//.test(textAfter))
314
+ context = context.prev;
315
+ while (context && !context.startOfLine)
316
+ context = context.prev;
317
+ if (context) return context.indent + indentUnit;
318
+ else return 0;
319
+ },
320
+
321
+ electricChars: "/",
322
+ blockCommentStart: "<!--",
323
+ blockCommentEnd: "-->",
324
+
325
+ configuration: parserConfig.htmlMode ? "html" : "xml",
326
+ helperType: parserConfig.htmlMode ? "html" : "xml"
327
+ };
328
+ });
329
+
330
+ CodeMirror.defineMIME("text/xml", "xml");
331
+ CodeMirror.defineMIME("application/xml", "xml");
332
+ if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
333
+ CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
@@ -0,0 +1,97 @@
1
+ CodeMirror.defineMode("yaml", function() {
2
+
3
+ var cons = ['true', 'false', 'on', 'off', 'yes', 'no'];
4
+ var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))$", 'i');
5
+
6
+ return {
7
+ token: function(stream, state) {
8
+ var ch = stream.peek();
9
+ var esc = state.escaped;
10
+ state.escaped = false;
11
+ /* comments */
12
+ if (ch == "#" && (stream.pos == 0 || /\s/.test(stream.string.charAt(stream.pos - 1)))) {
13
+ stream.skipToEnd(); return "comment";
14
+ }
15
+ if (state.literal && stream.indentation() > state.keyCol) {
16
+ stream.skipToEnd(); return "string";
17
+ } else if (state.literal) { state.literal = false; }
18
+ if (stream.sol()) {
19
+ state.keyCol = 0;
20
+ state.pair = false;
21
+ state.pairStart = false;
22
+ /* document start */
23
+ if(stream.match(/---/)) { return "def"; }
24
+ /* document end */
25
+ if (stream.match(/\.\.\./)) { return "def"; }
26
+ /* array list item */
27
+ if (stream.match(/\s*-\s+/)) { return 'meta'; }
28
+ }
29
+ /* inline pairs/lists */
30
+ if (stream.match(/^(\{|\}|\[|\])/)) {
31
+ if (ch == '{')
32
+ state.inlinePairs++;
33
+ else if (ch == '}')
34
+ state.inlinePairs--;
35
+ else if (ch == '[')
36
+ state.inlineList++;
37
+ else
38
+ state.inlineList--;
39
+ return 'meta';
40
+ }
41
+
42
+ /* list seperator */
43
+ if (state.inlineList > 0 && !esc && ch == ',') {
44
+ stream.next();
45
+ return 'meta';
46
+ }
47
+ /* pairs seperator */
48
+ if (state.inlinePairs > 0 && !esc && ch == ',') {
49
+ state.keyCol = 0;
50
+ state.pair = false;
51
+ state.pairStart = false;
52
+ stream.next();
53
+ return 'meta';
54
+ }
55
+
56
+ /* start of value of a pair */
57
+ if (state.pairStart) {
58
+ /* block literals */
59
+ if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return 'meta'; };
60
+ /* references */
61
+ if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return 'variable-2'; }
62
+ /* numbers */
63
+ if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return 'number'; }
64
+ if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return 'number'; }
65
+ /* keywords */
66
+ if (stream.match(keywordRegex)) { return 'keyword'; }
67
+ }
68
+
69
+ /* pairs (associative arrays) -> key */
70
+ if (!state.pair && stream.match(/^\s*\S+(?=\s*:($|\s))/i)) {
71
+ state.pair = true;
72
+ state.keyCol = stream.indentation();
73
+ return "atom";
74
+ }
75
+ if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return 'meta'; }
76
+
77
+ /* nothing found, continue */
78
+ state.pairStart = false;
79
+ state.escaped = (ch == '\\');
80
+ stream.next();
81
+ return null;
82
+ },
83
+ startState: function() {
84
+ return {
85
+ pair: false,
86
+ pairStart: false,
87
+ keyCol: 0,
88
+ inlinePairs: 0,
89
+ inlineList: 0,
90
+ literal: false,
91
+ escaped: false
92
+ };
93
+ }
94
+ };
95
+ });
96
+
97
+ CodeMirror.defineMIME("text/x-yaml", "yaml");
@@ -0,0 +1,336 @@
1
+ /*jslint newcap: true */
2
+ /*global XMLHttpRequest: false, inlineAttach: false, FormData: false */
3
+ /*
4
+ * Inline Text Attachment
5
+ *
6
+ * Author: Roy van Kaathoven
7
+ * Contact: ik@royvankaathoven.nl
8
+ */
9
+ (function(document, window) {
10
+ "use strict";
11
+
12
+ /**
13
+ * Simple function to merge the given objects
14
+ *
15
+ * @param {Object[]} object Multiple object parameters
16
+ * @returns {Object}
17
+ */
18
+ function merge() {
19
+ var result = {};
20
+ for (var i = arguments.length - 1; i >= 0; i--) {
21
+ var obj = arguments[i];
22
+ for (var k in obj) {
23
+ result[k] = obj[k];
24
+ }
25
+ }
26
+ return result;
27
+ }
28
+
29
+ /**
30
+ * @param {Object} options
31
+ */
32
+ window.inlineAttach = function(options, instance) {
33
+
34
+ var settings = merge(options, inlineAttach.defaults),
35
+ editor = instance,
36
+ filenameTag = '{filename}',
37
+ lastValue,
38
+ me = this;
39
+
40
+ /**
41
+ * Upload a given file blob
42
+ *
43
+ * @param {Blob} file
44
+ */
45
+ this.uploadFile = function(file) {
46
+ var formData = new FormData(),
47
+ xhr = new XMLHttpRequest(),
48
+ extension = 'png';
49
+
50
+ // Attach the file. If coming from clipboard, add a default filename (only works in Chrome for now)
51
+ // http://stackoverflow.com/questions/6664967/how-to-give-a-blob-uploaded-as-formdata-a-file-name
52
+ if (file.name) {
53
+ var fileNameMatches = file.name.match(/\.(.+)$/);
54
+ if (fileNameMatches) {
55
+ extension = fileNameMatches[1];
56
+ }
57
+ }
58
+ formData.append(settings.uploadFieldName, file, "image-" + Date.now() + "." + extension);
59
+
60
+ // Add any available extra parameters
61
+ if (typeof settings.extraParams === "object") {
62
+ for (var key in settings.extraParams) {
63
+ if (settings.extraParams.hasOwnProperty(key)) {
64
+ formData.append(key, settings.extraParams[key]);
65
+ }
66
+ }
67
+ }
68
+
69
+ xhr.open('POST', settings.uploadUrl);
70
+ xhr.onload = function() {
71
+ // If HTTP status is OK or Created
72
+ if (xhr.status === 200 || xhr.status === 201) {
73
+ var data = JSON.parse(xhr.responseText);
74
+ me.onUploadedFile(data);
75
+ } else {
76
+ me.onErrorUploading();
77
+ }
78
+ };
79
+ xhr.send(formData);
80
+ };
81
+
82
+ /**
83
+ * Check if the given file is allowed
84
+ *
85
+ * @param {File} file
86
+ */
87
+ this.isAllowedFile = function(file) {
88
+ return settings.allowedTypes.indexOf(file.type) >= 0;
89
+ };
90
+
91
+ /**
92
+ * When a file has finished uploading
93
+ *
94
+ * @param {Object} data
95
+ */
96
+ this.onUploadedFile = function(data) {
97
+ var result = settings.onUploadedFile(data),
98
+ filename = data[settings.downloadFieldName];
99
+ if (result !== false && filename) {
100
+ var text = editor.getValue().replace(lastValue, settings.urlText.replace(filenameTag, filename));
101
+ editor.setValue(text);
102
+ }
103
+ };
104
+
105
+ /**
106
+ * Custom upload handler
107
+ *
108
+ * @param {Blob} file
109
+ * @return {Boolean} when false is returned it will prevent default upload behavior
110
+ */
111
+ this.customUploadHandler = function(file) {
112
+ return settings.customUploadHandler(file);
113
+ };
114
+
115
+ /**
116
+ * When a file didn't upload properly.
117
+ * Override by passing your own onErrorUploading function with settings.
118
+ *
119
+ * @param {Object} data
120
+ */
121
+ this.onErrorUploading = function() {
122
+ var text = editor.getValue().replace(lastValue, "");
123
+ editor.setValue(text);
124
+ if (settings.customErrorHandler()) {
125
+ window.alert(settings.errorText);
126
+ }
127
+ };
128
+
129
+ /**
130
+ * Append a line of text at the bottom, ensuring there aren't unnecessary newlines
131
+ *
132
+ * @param {String} appended Current content
133
+ * @param {String} previous Value which should be appended after the current content
134
+ */
135
+ function appendInItsOwnLine(previous, appended) {
136
+ return (previous + "\n\n[[D]]" + appended)
137
+ .replace(/(\n{2,})\[\[D\]\]/, "\n\n")
138
+ .replace(/^(\n*)/, "");
139
+ }
140
+
141
+ /**
142
+ * When a file has been received by a drop or paste event
143
+ * @param {Blob} file
144
+ */
145
+ this.onReceivedFile = function(file) {
146
+ var result = settings.onReceivedFile(file);
147
+ if (result !== false) {
148
+ lastValue = settings.progressText;
149
+ editor.setValue(appendInItsOwnLine(editor.getValue(), lastValue));
150
+ }
151
+ };
152
+
153
+ /**
154
+ * Catches the paste event
155
+ *
156
+ * @param {Event} e
157
+ * @returns {Boolean} If a file is handled
158
+ */
159
+ this.onPaste = function(e) {
160
+ var result = false,
161
+ clipboardData = e.clipboardData,
162
+ items;
163
+
164
+ if (typeof clipboardData === "object") {
165
+
166
+ items = clipboardData.items || clipboardData.files || [];
167
+
168
+ for (var i = 0; i < items.length; i++) {
169
+ var item = items[i];
170
+ if (me.isAllowedFile(item)) {
171
+ result = true;
172
+ this.onReceivedFile(item.getAsFile());
173
+ if (this.customUploadHandler(item.getAsFile())) {
174
+ this.uploadFile(item.getAsFile());
175
+ }
176
+ }
177
+ }
178
+ }
179
+
180
+
181
+ return result;
182
+ };
183
+
184
+ /**
185
+ * Catches onDrop event
186
+ *
187
+ * @param {Event} e
188
+ * @returns {Boolean} If a file is handled
189
+ */
190
+ this.onDrop = function(e) {
191
+ var result = false;
192
+ for (var i = 0; i < e.dataTransfer.files.length; i++) {
193
+ var file = e.dataTransfer.files[i];
194
+ if (me.isAllowedFile(file)) {
195
+ result = true;
196
+ this.onReceivedFile(file);
197
+ if (this.customUploadHandler(file)) {
198
+ this.uploadFile(file);
199
+ }
200
+ }
201
+ }
202
+
203
+ return result;
204
+ };
205
+ };
206
+
207
+ /**
208
+ * Editor
209
+ */
210
+ window.inlineAttach.Editor = function(instance) {
211
+
212
+ var input = instance;
213
+
214
+ return {
215
+ getValue: function() {
216
+ return input.value;
217
+ },
218
+ setValue: function(val) {
219
+ input.value = val;
220
+ }
221
+ };
222
+ };
223
+
224
+ /**
225
+ * Default configuration
226
+ */
227
+ window.inlineAttach.defaults = {
228
+ /**
229
+ * URL to upload the attachment
230
+ */
231
+ uploadUrl: 'upload_attachment.php',
232
+
233
+ /**
234
+ * Request field name where the attachment will be placed in the form data
235
+ */
236
+ uploadFieldName: 'file',
237
+
238
+ /**
239
+ * Where is the filename placed in the response
240
+ */
241
+ downloadFieldName: 'filename',
242
+
243
+ /**
244
+ * Allowed types
245
+ */
246
+ allowedTypes: [
247
+ 'image/jpeg',
248
+ 'image/png',
249
+ 'image/jpg',
250
+ 'image/gif'
251
+ ],
252
+
253
+ /**
254
+ * Will be inserted on a drop or paste event
255
+ */
256
+ progressText: '![Uploading file...]()',
257
+
258
+ /**
259
+ * When a file has successfully been uploaded the last inserted text
260
+ * will be replaced by the urlText, the {filename} tag will be replaced
261
+ * by the filename that has been returned by the server
262
+ */
263
+ urlText: "![file]({filename})",
264
+
265
+ /**
266
+ * Text for default error when uploading
267
+ */
268
+ errorText: "Error uploading file",
269
+
270
+ /**
271
+ * Extra parameters which will be send when uploading a file
272
+ */
273
+ extraParams: {},
274
+
275
+ /**
276
+ * When a file is received by drag-drop or paste
277
+ */
278
+ onReceivedFile: function() {},
279
+
280
+ /**
281
+ * Custom upload handler
282
+ *
283
+ * @return {Boolean} when false is returned it will prevent default upload behavior
284
+ */
285
+ customUploadHandler: function() {
286
+ return true;
287
+ },
288
+
289
+ /**
290
+ * Custom error handler. Runs after removing the placeholder text and before the alert().
291
+ * Return false from this function to prevent the alert dialog.
292
+ *
293
+ * @return {Boolean} when false is returned it will prevent default error behavior
294
+ */
295
+ customErrorHandler: function() {
296
+ return true;
297
+ },
298
+
299
+ /**
300
+ * When a file has succesfully been uploaded
301
+ */
302
+ onUploadedFile: function() {}
303
+ };
304
+
305
+ /**
306
+ * Attach to a standard input field
307
+ *
308
+ * @param {Input} input
309
+ * @param {Object} options
310
+ */
311
+ window.inlineAttach.attachToInput = function(input, options) {
312
+
313
+ options = options || {};
314
+
315
+ var editor = new inlineAttach.Editor(input),
316
+ inlineattach = new inlineAttach(options, editor);
317
+
318
+ input.addEventListener('paste', function(e) {
319
+ inlineattach.onPaste(e);
320
+ }, false);
321
+ input.addEventListener('drop', function(e) {
322
+ e.stopPropagation();
323
+ e.preventDefault();
324
+ inlineattach.onDrop(e);
325
+ }, false);
326
+ input.addEventListener('dragenter', function(e) {
327
+ e.stopPropagation();
328
+ e.preventDefault();
329
+ }, false);
330
+ input.addEventListener('dragover', function(e) {
331
+ e.stopPropagation();
332
+ e.preventDefault();
333
+ }, false);
334
+ };
335
+
336
+ })(document, window);