-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathd.js
135 lines (115 loc) · 4.02 KB
/
d.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
const separator = '\x1e';
const search = '\u001f';
const DB_NAME = 'bangsDB';
const DB_VERSION = 1;
const STORE_NAME = 'bangStore';
const FILE_KEY = 'bang.az.gz';
function openDatabase() {
return new Promise((resolve, reject) => {
const request = indexedDB.open(DB_NAME, DB_VERSION);
request.onerror = (event) => {
reject(event.target.error);
};
request.onsuccess = (event) => {
resolve(event.target.result);
};
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains(STORE_NAME)) {
db.createObjectStore(STORE_NAME);
}
};
});
}
function getGzipData(db) {
return new Promise((resolve, reject) => {
const transaction = db.transaction(STORE_NAME, 'readonly');
const store = transaction.objectStore(STORE_NAME);
const getRequest = store.get(FILE_KEY);
getRequest.onsuccess = (event) => {
resolve(event.target.result);
};
getRequest.onerror = (event) => {
reject(event.target.error);
};
});
}
function storeGzipData(db, arrayBuffer) {
return new Promise((resolve, reject) => {
const transaction = db.transaction(STORE_NAME, 'readwrite');
const store = transaction.objectStore(STORE_NAME);
const putRequest = store.put(arrayBuffer, FILE_KEY);
putRequest.onsuccess = () => {
resolve();
};
putRequest.onerror = (event) => {
reject(event.target.error);
};
});
}
function decompressAndHandle(arrayBuffer) {
const compressedData = new Uint8Array(arrayBuffer);
fflate.gunzip(compressedData, (err, decompressedData) => {
if (err) {
console.error('Error decompressing:', err);
return;
}
const bangs = new TextDecoder().decode(decompressedData);
const lines = bangs.split('\n');
const dictionary = {};
lines.forEach(line => {
const parts = line.trim().split(separator);
if (parts.length === 2) {
const [key, value] = parts;
dictionary[key] = value;
}
});
doRedirect(dictionary);
});
}
function doRedirect(dictionary) {
const params = new URLSearchParams(window.location.search);
const queryParam = params.get('q');
if (queryParam) {
const tokens = queryParam.split(' ');
const bangTokenIndex = tokens.findIndex(token => token.startsWith('!'));
let bangKey = null;
if (bangTokenIndex > -1) {
bangKey = tokens[bangTokenIndex];
tokens.splice(bangTokenIndex, 1);
}
const searchQuery = tokens.join(' ');
if (bangKey && bangKey.startsWith('!')) {
bangKey = bangKey.slice(1);
}
if (bangKey && dictionary.hasOwnProperty(bangKey)) {
const urlTemplate = dictionary[bangKey];
window.location.href = urlTemplate.replace(search, encodeURIComponent(searchQuery));
} else {
window.location.href = 'https://www.google.com/search?q=' + encodeURIComponent(queryParam);
}
}
}
openDatabase()
.then(db => {
return getGzipData(db).then(cachedData => {
if (cachedData) {
decompressAndHandle(cachedData);
} else {
fetch('bang.az.gz')
.then(response => response.arrayBuffer())
.then(arrayBuffer => {
return storeGzipData(db, arrayBuffer).then(() => arrayBuffer);
})
.then(arrayBuffer => {
decompressAndHandle(arrayBuffer);
})
.catch(err => {
console.error('Error while fetching/storing/decompressing:', err);
});
}
});
})
.catch(err => {
console.error('Error opening or retrieving from IndexedDB:', err);
});