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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 }); | 69 }); |
70 } | 70 } |
71 | 71 |
72 function legacyFile(fileName) | 72 function legacyFile(fileName) |
73 { | 73 { |
74 let file = LegacyIO.resolveFilePath("adblockplus"); | 74 let file = LegacyIO.resolveFilePath("adblockplus"); |
75 file.append(fileName); | 75 file.append(fileName); |
76 return file; | 76 return file; |
77 } | 77 } |
78 | 78 |
| 79 let fallback = { |
| 80 readFromFile(fileName, listener) |
| 81 { |
| 82 let wrapper = { |
| 83 process(line) |
| 84 { |
| 85 if (line !== null) |
| 86 listener(line); |
| 87 } |
| 88 }; |
| 89 return callLegacy("readFromFile", legacyFile(fileName), wrapper); |
| 90 }, |
| 91 |
| 92 writeToFile(fileName, data) |
| 93 { |
| 94 return callLegacy("writeToFile", legacyFile(fileName), data); |
| 95 }, |
| 96 |
| 97 copyFile(fromFile, toFile) |
| 98 { |
| 99 return callLegacy("copyFile", legacyFile(fromFile), legacyFile(toFile)); |
| 100 }, |
| 101 |
| 102 renameFile(fromFile, newName) |
| 103 { |
| 104 return callLegacy("renameFile", legacyFile(fromFile), newName); |
| 105 }, |
| 106 |
| 107 removeFile(fileName) |
| 108 { |
| 109 return callLegacy("removeFile", legacyFile(fileName)); |
| 110 }, |
| 111 |
| 112 statFile(fileName) |
| 113 { |
| 114 return callLegacy("statFile", legacyFile(fileName)); |
| 115 } |
| 116 }; |
| 117 |
79 exports.IO = | 118 exports.IO = |
80 { | 119 { |
81 /** | 120 /** |
82 * @callback TextSink | 121 * @callback TextSink |
83 * @param {string} line | 122 * @param {string} line |
84 */ | 123 */ |
85 | 124 |
86 /** | 125 /** |
87 * Reads text lines from a file. | 126 * Reads text lines from a file. |
88 * @param {string} fileName | 127 * @param {string} fileName |
(...skipping 20 matching lines...) Expand all Loading... |
109 { | 148 { |
110 Utils.runAsync(processBatch); | 149 Utils.runAsync(processBatch); |
111 return; | 150 return; |
112 } | 151 } |
113 } | 152 } |
114 resolve(); | 153 resolve(); |
115 } | 154 } |
116 | 155 |
117 processBatch(); | 156 processBatch(); |
118 }); | 157 }); |
119 }).catch(error => | |
120 { | |
121 if (error == "NoSuchFile") | |
122 { | |
123 let wrapper = { | |
124 process(line) | |
125 { | |
126 if (line !== null) | |
127 listener(line); | |
128 } | |
129 }; | |
130 return callLegacy("readFromFile", legacyFile(fileName), wrapper); | |
131 } | |
132 throw error; | |
133 }); | 158 }); |
134 }, | 159 }, |
135 | 160 |
136 /** | 161 /** |
137 * Writes text lines to a file. | 162 * Writes text lines to a file. |
138 * @param {string} fileName | 163 * @param {string} fileName |
139 * Name of the file to be written | 164 * Name of the file to be written |
140 * @param {Iterable.<string>} data | 165 * @param {Iterable.<string>} data |
141 * An array-like or iterable object containing the lines (without line | 166 * An array-like or iterable object containing the lines (without line |
142 * endings) | 167 * endings) |
143 * @return {Promise} | 168 * @return {Promise} |
144 * Promise to be resolved or rejected once the operation is completed | 169 * Promise to be resolved or rejected once the operation is completed |
145 */ | 170 */ |
146 writeToFile(fileName, data) | 171 writeToFile(fileName, data) |
147 { | 172 { |
148 return callWebExt("writeToFile", fileName, Array.from(data)); | 173 return callWebExt("writeToFile", fileName, Array.from(data)); |
149 }, | 174 }, |
150 | 175 |
151 /** | 176 /** |
152 * Copies a file. | 177 * Copies a file. |
153 * @param {string} fromFile | 178 * @param {string} fromFile |
154 * Name of the file to be copied | 179 * Name of the file to be copied |
155 * @param {string} toFile | 180 * @param {string} toFile |
156 * Name of the file to be written, will be overwritten if exists | 181 * Name of the file to be written, will be overwritten if exists |
157 * @return {Promise} | 182 * @return {Promise} |
158 * Promise to be resolved or rejected once the operation is completed | 183 * Promise to be resolved or rejected once the operation is completed |
159 */ | 184 */ |
160 copyFile(fromFile, toFile) | 185 copyFile(fromFile, toFile) |
161 { | 186 { |
162 return callWebExt("copyFile", fromFile, toFile).catch(error => | 187 return callWebExt("copyFile", fromFile, toFile); |
163 { | |
164 if (error == "NoSuchFile") | |
165 return callLegacy("copyFile", legacyFile(fromFile), legacyFile(toFile)); | |
166 throw error; | |
167 }); | |
168 }, | 188 }, |
169 | 189 |
170 /** | 190 /** |
171 * Renames a file. | 191 * Renames a file. |
172 * @param {string} fromFile | 192 * @param {string} fromFile |
173 * Name of the file to be renamed | 193 * Name of the file to be renamed |
174 * @param {string} newName | 194 * @param {string} newName |
175 * New file name, will be overwritten if exists | 195 * New file name, will be overwritten if exists |
176 * @return {Promise} | 196 * @return {Promise} |
177 * Promise to be resolved or rejected once the operation is completed | 197 * Promise to be resolved or rejected once the operation is completed |
178 */ | 198 */ |
179 renameFile(fromFile, newName) | 199 renameFile(fromFile, newName) |
180 { | 200 { |
181 return callWebExt("renameFile", fromFile, newName).catch(error => | 201 return callWebExt("renameFile", fromFile, newName); |
182 { | |
183 if (error == "NoSuchFile") | |
184 return callLegacy("renameFile", legacyFile(fromFile), newName); | |
185 throw error; | |
186 }); | |
187 }, | 202 }, |
188 | 203 |
189 /** | 204 /** |
190 * Removes a file. | 205 * Removes a file. |
191 * @param {string} fileName | 206 * @param {string} fileName |
192 * Name of the file to be removed | 207 * Name of the file to be removed |
193 * @return {Promise} | 208 * @return {Promise} |
194 * Promise to be resolved or rejected once the operation is completed | 209 * Promise to be resolved or rejected once the operation is completed |
195 */ | 210 */ |
196 removeFile(fileName) | 211 removeFile(fileName) |
197 { | 212 { |
198 return callWebExt("removeFile", fileName).catch(error => | 213 return callWebExt("removeFile", fileName); |
199 { | |
200 if (error == "NoSuchFile") | |
201 return callLegacy("removeFile", legacyFile(fileName)); | |
202 throw error; | |
203 }); | |
204 }, | 214 }, |
205 | 215 |
206 /** | 216 /** |
207 * @typedef StatData | 217 * @typedef StatData |
208 * @type {object} | 218 * @type {object} |
209 * @property {boolean} exists | 219 * @property {boolean} exists |
210 * true if the file exists | 220 * true if the file exists |
211 * @property {number} lastModified | 221 * @property {number} lastModified |
212 * file modification time in milliseconds | 222 * file modification time in milliseconds |
213 */ | 223 */ |
214 | 224 |
215 /** | 225 /** |
216 * Retrieves file metadata. | 226 * Retrieves file metadata. |
217 * @param {string} fileName | 227 * @param {string} fileName |
218 * Name of the file to be looked up | 228 * Name of the file to be looked up |
219 * @return {Promise.<StatData>} | 229 * @return {Promise.<StatData>} |
220 * Promise to be resolved with file metadata once the operation is | 230 * Promise to be resolved with file metadata once the operation is |
221 * completed | 231 * completed |
222 */ | 232 */ |
223 statFile(fileName) | 233 statFile(fileName) |
224 { | 234 { |
225 return callWebExt("statFile", fileName).catch(error => | 235 return callWebExt("statFile", fileName); |
226 { | |
227 if (error == "NoSuchFile") | |
228 return callLegacy("statFile", legacyFile(fileName)); | |
229 throw error; | |
230 }); | |
231 } | 236 } |
232 }; | 237 }; |
| 238 |
| 239 let {application} = require("info"); |
| 240 if (application != "firefox" && application != "fennec2") |
| 241 { |
| 242 // Currently, only Firefox has a working WebExtensions implementation, other |
| 243 // applications should just use the fallback. |
| 244 exports.IO = fallback; |
| 245 } |
| 246 else |
| 247 { |
| 248 // Add fallbacks to IO methods - fall back to legacy I/O if file wasn't found. |
| 249 for (let name of Object.getOwnPropertyNames(exports.IO)) |
| 250 { |
| 251 // No fallback for writeToFile method, new data should always be stored to |
| 252 // new storage only. |
| 253 if (name == "writeToFile") |
| 254 continue; |
| 255 |
| 256 let method = exports.IO[name]; |
| 257 let fallbackMethod = fallback[name]; |
| 258 exports.IO[name] = (...args) => |
| 259 { |
| 260 return method(...args).catch(error => |
| 261 { |
| 262 if (error == "NoSuchFile") |
| 263 return fallbackMethod(...args); |
| 264 throw error; |
| 265 }); |
| 266 }; |
| 267 } |
| 268 } |
OLD | NEW |