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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165 | 1
1
1
1
1
780
780
882
846
846
846
846
757
3960
3960
3996
8542
3960
1217
1090
1108
1090
10
1090
823
823
823
823
823
18602
823
823
20044
823
17779
418623
34716
383907
823
768
768
1901
1901
16152
1901
320
320
40
320
| var shim = require('./shim');
var forEach = shim.forEach;
var filter = shim.filter;
var getKeys = shim.getKeys;
module.exports = {
// https://gist.github.com/1044128/
getOuterHTML: function (element) {
// jshint browser:true
if ('outerHTML' in element) return element.outerHTML;
var ns = "http://www.w3.org/1999/xhtml";
var container = document.createElementNS(ns, '_');
var xmlSerializer = new XMLSerializer();
var html;
if (document.xmlVersion) {
return xmlSerializer.serializeToString(element);
} else {
container.appendChild(element.cloneNode(false));
html = container.innerHTML.replace('><', '>' + element.innerHTML + '<');
container.innerHTML = '';
return html;
}
},
// Returns true if object is a DOM element.
isDOMElement: function (object) {
Iif (typeof HTMLElement === 'object') {
return object instanceof HTMLElement;
} else {
return object &&
typeof object === 'object' &&
object.nodeType === 1 &&
typeof object.nodeName === 'string';
}
},
isArray: function (ar) {
return Object.prototype.toString.call(ar) === '[object Array]';
},
isRegExp: function (re) {
var s;
try {
s = '' + re;
} catch (e) {
return false;
}
return re instanceof RegExp || // easy case
// duck-type for context-switching evalcx case
typeof(re) === 'function' &&
re.constructor.name === 'RegExp' &&
re.compile &&
re.test &&
re.exec &&
s.match(/^\/.*\/[gim]{0,3}$/);
},
isError: function (err) {
return typeof err === 'object' && Object.prototype.toString.call(err) === '[object Error]';
},
extend: function (target) {
var sources = Array.prototype.slice.call(arguments, 1);
forEach(sources, function (source) {
forEach(getKeys(source), function (key) {
target[key] = source[key];
});
});
return target;
},
isUndefinedOrNull: function (value) {
return value === null || value === undefined;
},
isArguments: function (object) {
return Object.prototype.toString.call(object) === '[object Arguments]';
},
getKeysOfDefinedProperties: function (object) {
var keys = filter(getKeys(object), function (key) {
return typeof object[key] !== 'undefined';
});
// The 'message' property of Error instances is enumerable for some reason, but we want
// to include it in the set when comparing:
if (Object.prototype.toString.call(object) === '[object Error]') {
keys.push('message');
}
return keys;
},
/**
* Levenshtein distance algorithm from wikipedia
* http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#JavaScript
*/
levenshteinDistance: function (a, b) {
Iif (a.length === 0) return b.length;
Iif (b.length === 0) return a.length;
var matrix = [];
// increment along the first column of each row
var i;
for (i = 0; i <= b.length; i += 1) {
matrix[i] = [i];
}
// increment each column in the first row
var j;
for (j = 0; j <= a.length; j += 1) {
matrix[0][j] = j;
}
// Fill in the rest of the matrix
for (i = 1; i <= b.length; i += 1) {
for (j = 1; j <= a.length; j += 1) {
if (b.charAt(i - 1) === a.charAt(j - 1)) {
matrix[i][j] = matrix[i - 1][j - 1];
} else {
matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
Math.min(matrix[i][j - 1] + 1, // insertion
matrix[i - 1][j] + 1)); // deletion
}
}
}
return matrix[b.length][a.length];
},
truncateStack: function (err, fn) {
Eif (Error.captureStackTrace) {
Error.captureStackTrace(err, fn);
} else if ('stack' in err) {
// Excludes IE<10, and fn cannot be anonymous for this backup plan to work:
var stackEntries = err.stack.split(/\r\n?|\n\r?/),
needle = 'at ' + fn.name + ' ';
for (var i = 0 ; i < stackEntries.length ; i += 1) {
if (stackEntries[i].indexOf(needle) !== -1) {
stackEntries.splice(1, i);
err.stack = stackEntries.join("\n");
}
}
}
},
findFirst: function (arr, predicate, thisObj) {
var scope = thisObj || null;
for (var i = 0 ; i < arr.length ; i += 1) {
if (predicate.call(scope, arr[i], i, arr)) {
return arr[i];
}
}
return null;
},
leftPad: function (str, width, ch) {
ch = ch || ' ';
while (str.length < width) {
str = ch + str;
}
return str;
}
};
|