| 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 |