Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80766 views
1
/* -*- Mode: js; js-indent-level: 2; -*- */
2
/*
3
* Copyright 2011 Mozilla Foundation and contributors
4
* Licensed under the New BSD license. See LICENSE or:
5
* http://opensource.org/licenses/BSD-3-Clause
6
*/
7
if (typeof define !== 'function') {
8
var define = require('amdefine')(module, require);
9
}
10
define(function (require, exports, module) {
11
12
/**
13
* This is a helper function for getting values from parameter/options
14
* objects.
15
*
16
* @param args The object we are extracting values from
17
* @param name The name of the property we are getting.
18
* @param defaultValue An optional value to return if the property is missing
19
* from the object. If this is not specified and the property is missing, an
20
* error will be thrown.
21
*/
22
function getArg(aArgs, aName, aDefaultValue) {
23
if (aName in aArgs) {
24
return aArgs[aName];
25
} else if (arguments.length === 3) {
26
return aDefaultValue;
27
} else {
28
throw new Error('"' + aName + '" is a required argument.');
29
}
30
}
31
exports.getArg = getArg;
32
33
var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/;
34
var dataUrlRegexp = /^data:.+\,.+$/;
35
36
function urlParse(aUrl) {
37
var match = aUrl.match(urlRegexp);
38
if (!match) {
39
return null;
40
}
41
return {
42
scheme: match[1],
43
auth: match[2],
44
host: match[3],
45
port: match[4],
46
path: match[5]
47
};
48
}
49
exports.urlParse = urlParse;
50
51
function urlGenerate(aParsedUrl) {
52
var url = '';
53
if (aParsedUrl.scheme) {
54
url += aParsedUrl.scheme + ':';
55
}
56
url += '//';
57
if (aParsedUrl.auth) {
58
url += aParsedUrl.auth + '@';
59
}
60
if (aParsedUrl.host) {
61
url += aParsedUrl.host;
62
}
63
if (aParsedUrl.port) {
64
url += ":" + aParsedUrl.port
65
}
66
if (aParsedUrl.path) {
67
url += aParsedUrl.path;
68
}
69
return url;
70
}
71
exports.urlGenerate = urlGenerate;
72
73
/**
74
* Normalizes a path, or the path portion of a URL:
75
*
76
* - Replaces consequtive slashes with one slash.
77
* - Removes unnecessary '.' parts.
78
* - Removes unnecessary '<dir>/..' parts.
79
*
80
* Based on code in the Node.js 'path' core module.
81
*
82
* @param aPath The path or url to normalize.
83
*/
84
function normalize(aPath) {
85
var path = aPath;
86
var url = urlParse(aPath);
87
if (url) {
88
if (!url.path) {
89
return aPath;
90
}
91
path = url.path;
92
}
93
var isAbsolute = (path.charAt(0) === '/');
94
95
var parts = path.split(/\/+/);
96
for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
97
part = parts[i];
98
if (part === '.') {
99
parts.splice(i, 1);
100
} else if (part === '..') {
101
up++;
102
} else if (up > 0) {
103
if (part === '') {
104
// The first part is blank if the path is absolute. Trying to go
105
// above the root is a no-op. Therefore we can remove all '..' parts
106
// directly after the root.
107
parts.splice(i + 1, up);
108
up = 0;
109
} else {
110
parts.splice(i, 2);
111
up--;
112
}
113
}
114
}
115
path = parts.join('/');
116
117
if (path === '') {
118
path = isAbsolute ? '/' : '.';
119
}
120
121
if (url) {
122
url.path = path;
123
return urlGenerate(url);
124
}
125
return path;
126
}
127
exports.normalize = normalize;
128
129
/**
130
* Joins two paths/URLs.
131
*
132
* @param aRoot The root path or URL.
133
* @param aPath The path or URL to be joined with the root.
134
*
135
* - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
136
* scheme-relative URL: Then the scheme of aRoot, if any, is prepended
137
* first.
138
* - Otherwise aPath is a path. If aRoot is a URL, then its path portion
139
* is updated with the result and aRoot is returned. Otherwise the result
140
* is returned.
141
* - If aPath is absolute, the result is aPath.
142
* - Otherwise the two paths are joined with a slash.
143
* - Joining for example 'http://' and 'www.example.com' is also supported.
144
*/
145
function join(aRoot, aPath) {
146
var aPathUrl = urlParse(aPath);
147
var aRootUrl = urlParse(aRoot);
148
if (aRootUrl) {
149
aRoot = aRootUrl.path || '/';
150
}
151
152
// `join(foo, '//www.example.org')`
153
if (aPathUrl && !aPathUrl.scheme) {
154
if (aRootUrl) {
155
aPathUrl.scheme = aRootUrl.scheme;
156
}
157
return urlGenerate(aPathUrl);
158
}
159
160
if (aPathUrl || aPath.match(dataUrlRegexp)) {
161
return aPath;
162
}
163
164
// `join('http://', 'www.example.com')`
165
if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
166
aRootUrl.host = aPath;
167
return urlGenerate(aRootUrl);
168
}
169
170
var joined = aPath.charAt(0) === '/'
171
? aPath
172
: normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
173
174
if (aRootUrl) {
175
aRootUrl.path = joined;
176
return urlGenerate(aRootUrl);
177
}
178
return joined;
179
}
180
exports.join = join;
181
182
/**
183
* Because behavior goes wacky when you set `__proto__` on objects, we
184
* have to prefix all the strings in our set with an arbitrary character.
185
*
186
* See https://github.com/mozilla/source-map/pull/31 and
187
* https://github.com/mozilla/source-map/issues/30
188
*
189
* @param String aStr
190
*/
191
function toSetString(aStr) {
192
return '$' + aStr;
193
}
194
exports.toSetString = toSetString;
195
196
function fromSetString(aStr) {
197
return aStr.substr(1);
198
}
199
exports.fromSetString = fromSetString;
200
201
function relative(aRoot, aPath) {
202
aRoot = aRoot.replace(/\/$/, '');
203
204
var url = urlParse(aRoot);
205
if (aPath.charAt(0) == "/" && url && url.path == "/") {
206
return aPath.slice(1);
207
}
208
209
return aPath.indexOf(aRoot + '/') === 0
210
? aPath.substr(aRoot.length + 1)
211
: aPath;
212
}
213
exports.relative = relative;
214
215
function strcmp(aStr1, aStr2) {
216
var s1 = aStr1 || "";
217
var s2 = aStr2 || "";
218
return (s1 > s2) - (s1 < s2);
219
}
220
221
/**
222
* Comparator between two mappings where the original positions are compared.
223
*
224
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
225
* mappings with the same original source/line/column, but different generated
226
* line and column the same. Useful when searching for a mapping with a
227
* stubbed out mapping.
228
*/
229
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
230
var cmp;
231
232
cmp = strcmp(mappingA.source, mappingB.source);
233
if (cmp) {
234
return cmp;
235
}
236
237
cmp = mappingA.originalLine - mappingB.originalLine;
238
if (cmp) {
239
return cmp;
240
}
241
242
cmp = mappingA.originalColumn - mappingB.originalColumn;
243
if (cmp || onlyCompareOriginal) {
244
return cmp;
245
}
246
247
cmp = strcmp(mappingA.name, mappingB.name);
248
if (cmp) {
249
return cmp;
250
}
251
252
cmp = mappingA.generatedLine - mappingB.generatedLine;
253
if (cmp) {
254
return cmp;
255
}
256
257
return mappingA.generatedColumn - mappingB.generatedColumn;
258
};
259
exports.compareByOriginalPositions = compareByOriginalPositions;
260
261
/**
262
* Comparator between two mappings where the generated positions are
263
* compared.
264
*
265
* Optionally pass in `true` as `onlyCompareGenerated` to consider two
266
* mappings with the same generated line and column, but different
267
* source/name/original line and column the same. Useful when searching for a
268
* mapping with a stubbed out mapping.
269
*/
270
function compareByGeneratedPositions(mappingA, mappingB, onlyCompareGenerated) {
271
var cmp;
272
273
cmp = mappingA.generatedLine - mappingB.generatedLine;
274
if (cmp) {
275
return cmp;
276
}
277
278
cmp = mappingA.generatedColumn - mappingB.generatedColumn;
279
if (cmp || onlyCompareGenerated) {
280
return cmp;
281
}
282
283
cmp = strcmp(mappingA.source, mappingB.source);
284
if (cmp) {
285
return cmp;
286
}
287
288
cmp = mappingA.originalLine - mappingB.originalLine;
289
if (cmp) {
290
return cmp;
291
}
292
293
cmp = mappingA.originalColumn - mappingB.originalColumn;
294
if (cmp) {
295
return cmp;
296
}
297
298
return strcmp(mappingA.name, mappingB.name);
299
};
300
exports.compareByGeneratedPositions = compareByGeneratedPositions;
301
302
});
303
304