Left: | ||
Right: |
OLD | NEW |
---|---|
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-2017 eyeo GmbH | 3 * Copyright (C) 2006-2017 eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
48 { | 48 { |
49 return new Promise((resolve, reject) => | 49 return new Promise((resolve, reject) => |
50 { | 50 { |
51 let id = ++messageID; | 51 let id = ++messageID; |
52 messageCallbacks.set(id, {resolve, reject}); | 52 messageCallbacks.set(id, {resolve, reject}); |
53 port.postMessage({id, method, args}); | 53 port.postMessage({id, method, args}); |
54 }); | 54 }); |
55 }); | 55 }); |
56 } | 56 } |
57 | 57 |
58 function attachCallback(promise, callback, fallback) | 58 function callLegacy(method, ...args) |
59 { | 59 { |
60 promise.then(result => | 60 return new Promise((resolve, reject) => |
61 { | 61 { |
62 callback(null, result); | 62 LegacyIO[method](...args, (error, result) => |
63 }).catch(error => | 63 { |
64 { | 64 if (error) |
65 if (fallback && error == "NoSuchFile") | 65 reject(error); |
66 fallback(); | 66 else |
67 else | 67 resolve(result); |
68 callback(error); | 68 }); |
69 }); | 69 }); |
70 } | 70 } |
71 | 71 |
72 function legacyFile(fileName) | |
73 { | |
74 let file = LegacyIO.resolveFilePath("adblockplus"); | |
75 file.append(fileName); | |
76 return file; | |
77 } | |
78 | |
72 exports.IO = | 79 exports.IO = |
73 { | 80 { |
74 resolveFilePath: LegacyIO.resolveFilePath, | 81 /** |
82 * @callback TextSink | |
83 * @param {string} line | |
84 */ | |
75 | 85 |
76 /** | 86 /** |
77 * Reads strings from a file asynchronously, calls listener.process() with | 87 * Reads text lines from a file. |
78 * each line read and with a null parameter once the read operation is done. | 88 * @param {string} fileName |
79 * The callback will be called when the operation is done. | 89 * Name of the file to be read |
90 * @param {TextSink} listener | |
91 * Function that will be called for each line in the file | |
92 * @return {Promise} | |
93 * Promise to be resolved or rejected once the operation is completed | |
80 */ | 94 */ |
81 readFromFile(/**nsIFile*/ file, /**Object*/ listener, /**Function*/ callback) | 95 readFromFile(fileName, listener) |
82 { | 96 { |
83 attachCallback( | 97 return callWebExt("readFromFile", fileName).then(contents => |
84 callWebExt("readFromFile", file.leafName).then(contents => | 98 { |
99 return new Promise((resolve, reject) => | |
85 { | 100 { |
86 return new Promise((resolve, reject) => | 101 let lineIndex = 0; |
102 | |
103 function processBatch() | |
87 { | 104 { |
88 let lineIndex = 0; | 105 while (lineIndex < contents.length) |
106 { | |
107 listener(contents[lineIndex++]); | |
108 if (lineIndex % 1000 == 0) | |
109 { | |
110 Utils.runAsync(processBatch); | |
111 return; | |
112 } | |
113 } | |
114 resolve(); | |
115 } | |
89 | 116 |
90 function processBatch() | 117 processBatch(); |
118 }); | |
119 }).catch(error => | |
120 { | |
121 if (error == "NoSuchFile") | |
122 { | |
123 let wrapper = { | |
124 process(line) | |
91 { | 125 { |
92 while (lineIndex < contents.length) | 126 if (line !== null) |
93 { | 127 listener(line); |
94 listener.process(contents[lineIndex++]); | |
95 if (lineIndex % 1000 == 0) | |
96 { | |
97 Utils.runAsync(processBatch); | |
98 return; | |
99 } | |
100 } | |
101 | |
102 listener.process(null); | |
103 resolve(); | |
104 } | 128 } |
105 | 129 }; |
106 processBatch(); | 130 return callLegacy("readFromFile", legacyFile(fileName), wrapper); |
107 }); | 131 } |
108 }), | 132 throw error; |
109 callback, | 133 }); |
110 () => LegacyIO.readFromFile(file, listener, callback) | |
111 ); | |
112 }, | 134 }, |
113 | 135 |
114 /** | 136 /** |
115 * Writes string data to a file in UTF-8 format asynchronously. The callback | 137 * Writes text lines to a file. |
116 * will be called when the write operation is done. | 138 * @param {string} fileName |
139 * Name of the file to be written | |
140 * @param {Iterable.<string>} data | |
141 * An array-like or iterable object containing the lines (without line | |
142 * endings) | |
143 * @return {Promise} | |
144 * Promise to be resolved or rejected once the operation is completed | |
117 */ | 145 */ |
118 writeToFile(/**nsIFile*/ file, /**Iterator*/ data, /**Function*/ callback) | 146 writeToFile(fileName, data) |
119 { | 147 { |
120 attachCallback( | 148 return callWebExt("writeToFile", fileName, Array.from(data)); |
121 callWebExt("writeToFile", file.leafName, Array.from(data)), | |
122 callback | |
123 ); | |
124 }, | 149 }, |
125 | 150 |
126 /** | 151 /** |
127 * Copies a file asynchronously. The callback will be called when the copy | 152 * Copies a file. |
128 * operation is done. | 153 * @param {string} fromFile |
154 * Name of the file to be copied | |
155 * @param {string} toFile | |
156 * Name of the file to be written, will be overwritten if exists | |
157 * @return {Promise} | |
158 * Promise to be resolved or rejected once the operation is completed | |
129 */ | 159 */ |
130 copyFile(/**nsIFile*/ fromFile, /**nsIFile*/ toFile, /**Function*/ callback) | 160 copyFile(fromFile, toFile) |
131 { | 161 { |
132 attachCallback( | 162 return callWebExt("copyFile", fromFile, toFile).catch(error => |
133 callWebExt("copyFile", fromFile.leafName, toFile.leafName), | 163 { |
134 callback, | 164 if (error == "NoSuchFile") |
kzar
2017/04/20 10:25:07
It seems like this pattern is repeated quite a bit
Wladimir Palant
2017/04/20 12:02:06
I thought about it but couldn't see a way requirin
kzar
2017/04/20 12:11:59
Hmm I guess not. I didn't realise the arguments pa
| |
135 () => LegacyIO.copyFile(fromFile, toFile, callback) | 165 return callLegacy("copyFile", legacyFile(fromFile), legacyFile(toFile)); |
136 ); | 166 throw error; |
167 }); | |
137 }, | 168 }, |
138 | 169 |
139 /** | 170 /** |
140 * Renames a file within the same directory, will call callback when done. | 171 * Renames a file. |
172 * @param {string} fromFile | |
173 * Name of the file to be renamed | |
174 * @param {string} newName | |
175 * New file name, will be overwritten if exists | |
176 * @return {Promise} | |
177 * Promise to be resolved or rejected once the operation is completed | |
141 */ | 178 */ |
142 renameFile(/**nsIFile*/ fromFile, /**String*/ newName, /**Function*/ callback) | 179 renameFile(fromFile, newName) |
143 { | 180 { |
144 attachCallback( | 181 return callWebExt("renameFile", fromFile, newName).catch(error => |
145 callWebExt("renameFile", fromFile.leafName, newName), | 182 { |
146 callback, | 183 if (error == "NoSuchFile") |
147 () => LegacyIO.renameFile(fromFile, newName, callback) | 184 return callLegacy("renameFile", legacyFile(fromFile), newName); |
148 ); | 185 throw error; |
186 }); | |
149 }, | 187 }, |
150 | 188 |
151 /** | 189 /** |
152 * Removes a file, will call callback when done. | 190 * Removes a file. |
191 * @param {string} fileName | |
192 * Name of the file to be removed | |
193 * @return {Promise} | |
194 * Promise to be resolved or rejected once the operation is completed | |
153 */ | 195 */ |
154 removeFile(/**nsIFile*/ file, /**Function*/ callback) | 196 removeFile(fileName) |
155 { | 197 { |
156 attachCallback( | 198 return callWebExt("removeFile", fileName).catch(error => |
157 callWebExt("removeFile", file.leafName), | 199 { |
158 callback, | 200 if (error == "NoSuchFile") |
159 () => LegacyIO.removeFile(file, callback) | 201 return callLegacy("removeFile", legacyFile(fileName)); |
160 ); | 202 throw error; |
203 }); | |
161 }, | 204 }, |
162 | 205 |
163 /** | 206 /** |
164 * Gets file information such as whether the file exists. | 207 * @typedef StatData |
208 * @type {object} | |
209 * @property {boolean} exists | |
210 * true if the file exists | |
211 * @property {number} lastModified | |
212 * file modification time in milliseconds | |
165 */ | 213 */ |
166 statFile(/**nsIFile*/ file, /**Function*/ callback) | 214 |
215 /** | |
216 * Retrieves file metadata. | |
217 * @param {string} fileName | |
218 * Name of the file to be looked up | |
219 * @return {Promise.<StatData>} | |
220 * Promise to be resolved with file metadata once the operation is | |
221 * completed | |
222 */ | |
223 statFile(fileName) | |
167 { | 224 { |
168 attachCallback( | 225 return callWebExt("statFile", fileName).catch(error => |
169 callWebExt("statFile", file.leafName), | 226 { |
170 callback, | 227 if (error == "NoSuchFile") |
171 () => LegacyIO.statFile(file, callback) | 228 return callLegacy("statFile", legacyFile(fileName)); |
172 ); | 229 throw error; |
230 }); | |
173 } | 231 } |
174 }; | 232 }; |
OLD | NEW |