This repository has been archived by the owner on Jan 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
/
utils.js
122 lines (107 loc) · 3.71 KB
/
utils.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
'use strict';
const Qs = require('qs');
const Reporting = require('./reporting');
/* eslint-disable */
// Source: https://gist.github.com/jed/982883.
exports.uuidV1 = function uuidV1(a){
return a?(a^Math.random()*16>>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, uuidV1)
}
/* eslint-enable */
function unlessError(func, onError) {
// Decorate chrome callbacks to notice errors.
// If an error occurs, call onError.
return function unlessErrorWrapper() {
// can't use an arrow function here because we need our own `this`.
if (chrome.extension.lastError) {
console.error('unlessError:', chrome.extension.lastError.message);
Reporting.Raven.captureMessage(chrome.extension.lastError.message, {
tags: {
funcName: func.name,
},
extra: {
func,
location: 'Utils.unlessError',
error: chrome.extension.lastError,
this: this,
arguments: arguments, // eslint-disable-line object-shorthand
},
stacktrace: true,
});
if (typeof onError !== 'undefined') {
onError(chrome.extension.lastError);
}
} else {
func.apply(this, arguments);
}
};
}
exports.unlessError = unlessError;
exports.focusOrCreateExtensionTab = function focusOrCreateExtensionTab(url) {
chrome.tabs.create({url, active: true}, unlessError(t => console.debug('created', t)));
// There seems to be a bug in Chrome preventing tabs.query from working as expected.
// chrome.tabs.query({url}, unlessError(tabs => {
// console.info('tab query for', url, 'yields', JSON.stringify(tabs, null, '\t'));
// if (tabs.length) {
// chrome.tabs.update(tabs[0].id, {active: true}, unlessError(t => console.log('selected', t)));
// } else {
// chrome.tabs.create({url, active: true}, unlessError(t => console.log('created', t)));
// }
// }));
};
exports.goToManager = function goToManager(userId) {
window.location.href = `/html/playlists.html?${Qs.stringify({userId})}`;
};
exports.goToPlaylistEditor = function goToPlaylistEditor(userId, playlistId, duplicating) {
// Navigate to the playlist details page for an existing playlist, or a playlist being duplicated.
const qstring = {userId};
if (duplicating) {
qstring.duplicateId = playlistId;
} else {
qstring.id = playlistId;
}
window.location.href = `/html/playlist.html?${Qs.stringify(qstring)}`;
};
exports.maximumIncreasingSubsequenceIndices = function maximumIncreasingSubsequenceIndices(a) {
if (a.length === 0) {
return [];
}
return findSequence(a, findIndex(a));
};
// Source below here: https://rosettacode.org/wiki/Longest_increasing_subsequence#JavaScript
function range(len) {
const a = [];
for (let i = 0; i < len; i++) {
a.push(1);
}
return a;
}
/* eslint-disable */
function findIndex(input) {
var len = input.length;
var maxSeqEndingHere = range(len).map(function() {
return 1;
});
for (var i = 0; i < len; i++)
for (var j = i - 1; j >= 0; j--)
if (input[i] > input[j] && maxSeqEndingHere[j] >= maxSeqEndingHere[i])
maxSeqEndingHere[i] = maxSeqEndingHere[j] + 1;
return maxSeqEndingHere;
}
function findSequence(input, result) {
var maxValue = Math.max.apply(null, result);
// I'm not actually sure if using lastIndexOf here makes a noticeable difference.
// It just controls which entry we move when we could pick from multiple.
var maxIndex = result.lastIndexOf(maxValue);
var output = [];
output.push(maxIndex);
for (var i = maxIndex; i >= 0; i--) {
if (maxValue == 0) break;
if (input[maxIndex] > input[i] && result[i] == maxValue - 1) {
output.push(i);
maxValue--;
}
}
output.reverse();
return output;
}
/* eslint-enable */