This repository has been archived by the owner on Dec 12, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
base64.js
150 lines (131 loc) · 4.2 KB
/
base64.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/**
* Encodes/decodes image under cursor to/from base64
* @param {IEmmetEditor} editor
*/
if (typeof module === 'object' && typeof define !== 'function') {
var define = function (factory) {
module.exports = factory(require, exports, module);
};
}
define(function(require, exports, module) {
var file = require('../plugin/file');
var base64 = require('../utils/base64');
var actionUtils = require('../utils/action');
var editorUtils = require('../utils/editor');
/**
* Test if <code>text</code> starts with <code>token</code> at <code>pos</code>
* position. If <code>pos</code> is omitted, search from beginning of text
* @param {String} token Token to test
* @param {String} text Where to search
* @param {Number} pos Position where to start search
* @return {Boolean}
* @since 0.65
*/
function startsWith(token, text, pos) {
pos = pos || 0;
return text.charAt(pos) == token.charAt(0) && text.substr(pos, token.length) == token;
}
/**
* Encodes image to base64
*
* @param {IEmmetEditor} editor
* @param {String} imgPath Path to image
* @param {Number} pos Caret position where image is located in the editor
* @return {Boolean}
*/
function encodeToBase64(editor, imgPath, pos) {
var editorFile = editor.getFilePath();
var defaultMimeType = 'application/octet-stream';
if (editorFile === null) {
throw "You should save your file before using this action";
}
// locate real image path
file.locateFile(editorFile, imgPath, function(realImgPath) {
if (realImgPath === null) {
throw "Can't find " + imgPath + ' file';
}
file.read(realImgPath, function(err, content) {
if (err) {
throw 'Unable to read ' + realImgPath + ': ' + err;
}
var b64 = base64.encode(String(content));
if (!b64) {
throw "Can't encode file content to base64";
}
b64 = 'data:' + (actionUtils.mimeTypes[String(file.getExt(realImgPath))] || defaultMimeType) +
';base64,' + b64;
editor.replaceContent('$0' + b64, pos, pos + imgPath.length);
});
});
return true;
}
/**
* Decodes base64 string back to file.
* @param {IEmmetEditor} editor
* @param {String} filePath to new image
* @param {String} data Base64-encoded file content
* @param {Number} pos Caret position where image is located in the editor
*/
function decodeFromBase64(editor, filePath, data, pos) {
// ask user to enter path to file
filePath = filePath || String(editor.prompt('Enter path to file (absolute or relative)'));
if (!filePath) {
return false;
}
var editorFile = editor.getFilePath();
file.createPath(editorFile, filePath, function(err, absPath) {
if (err || !absPath) {
throw "Can't save file";
}
var content = data.replace(/^data\:.+?;.+?,/, '');
file.save(absPath, base64.decode(content), function(err) {
if (err) {
throw 'Unable to save ' + absPath + ': ' + err;
}
editor.replaceContent('$0' + filePath, pos, pos + data.length);
});
});
return true;
}
return {
/**
* Action to encode or decode file to data:url
* @param {IEmmetEditor} editor Editor instance
* @param {String} syntax Current document syntax
* @param {String} profile Output profile name
* @return {Boolean}
*/
encodeDecodeDataUrlAction: function(editor, filepath) {
var data = String(editor.getSelection());
var caretPos = editor.getCaretPos();
var info = editorUtils.outputInfo(editor);
if (!data) {
// no selection, try to find image bounds from current caret position
var text = info.content, m;
while (caretPos-- >= 0) {
if (startsWith('src=', text, caretPos)) { // found <img src="">
if ((m = text.substr(caretPos).match(/^(src=(["'])?)([^'"<>\s]+)\1?/))) {
data = m[3];
caretPos += m[1].length;
}
break;
} else if (startsWith('url(', text, caretPos)) { // found CSS url() pattern
if ((m = text.substr(caretPos).match(/^(url\((['"])?)([^'"\)\s]+)\1?/))) {
data = m[3];
caretPos += m[1].length;
}
break;
}
}
}
if (data) {
if (startsWith('data:', data)) {
return decodeFromBase64(editor, filepath, data, caretPos);
} else {
return encodeToBase64(editor, data, caretPos);
}
}
return false;
}
};
});