165 """ |
164 """ |
166 Public method to get the list of included URLs. |
165 Public method to get the list of included URLs. |
167 |
166 |
168 @return list of included URLs (list of strings) |
167 @return list of included URLs (list of strings) |
169 """ |
168 """ |
170 list = [] |
169 return self.__include[:] |
171 for matcher in self.__include: |
|
172 list.append(matcher.pattern()) |
|
173 return list |
|
174 |
170 |
175 def exclude(self): |
171 def exclude(self): |
176 """ |
172 """ |
177 Public method to get the list of excluded URLs. |
173 Public method to get the list of excluded URLs. |
178 |
174 |
179 @return list of excluded URLs (list of strings) |
175 @return list of excluded URLs (list of strings) |
180 """ |
176 """ |
181 list = [] |
177 return self.__exclude[:] |
182 for matcher in self.__exclude: |
|
183 list.append(matcher.pattern()) |
|
184 return list |
|
185 |
178 |
186 def script(self): |
179 def script(self): |
187 """ |
180 """ |
188 Public method to get the Javascript source. |
181 Public method to get the Javascript source. |
189 |
182 |
190 @return Javascript source (string) |
183 @return Javascript source (string) |
191 """ |
184 """ |
192 return self.__script |
185 return self.__script |
193 |
186 |
194 def metaData(self): |
|
195 """ |
|
196 Public method to get the script meta information. |
|
197 |
|
198 @return script meta information |
|
199 @rtype str |
|
200 """ |
|
201 return self.__metaData |
|
202 |
|
203 def fileName(self): |
187 def fileName(self): |
204 """ |
188 """ |
205 Public method to get the path of the Javascript file. |
189 Public method to get the path of the Javascript file. |
206 |
190 |
207 @return path path of the Javascript file (string) |
191 @return path path of the Javascript file (string) |
208 """ |
192 """ |
209 return self.__fileName |
193 return self.__fileName |
210 |
|
211 def match(self, urlString): |
|
212 """ |
|
213 Public method to check, if the script matches the given URL. |
|
214 |
|
215 @param urlString URL (string) |
|
216 @return flag indicating a match (boolean) |
|
217 """ |
|
218 if not self.isEnabled(): |
|
219 return False |
|
220 |
|
221 for matcher in self.__exclude: |
|
222 if matcher.match(urlString): |
|
223 return False |
|
224 |
|
225 for matcher in self.__include: |
|
226 if matcher.match(urlString): |
|
227 return True |
|
228 |
|
229 return False |
|
230 |
194 |
231 @pyqtSlot(str) |
195 @pyqtSlot(str) |
232 def __watchedFileChanged(self, fileName): |
196 def __watchedFileChanged(self, fileName): |
233 """ |
197 """ |
234 Private slot handling changes of the script file. |
198 Private slot handling changes of the script file. |
323 |
286 |
324 ## elif key == "@updateURL": |
287 ## elif key == "@updateURL": |
325 ## self.__downloadUrl = QUrl(value) |
288 ## self.__downloadUrl = QUrl(value) |
326 ## |
289 ## |
327 elif key in ["@include", "@match"]: |
290 elif key in ["@include", "@match"]: |
328 self.__include.append(GreaseMonkeyUrlMatcher(value)) |
291 self.__include.append(value) |
329 |
292 |
330 elif key in ["@exclude", "@exclude_match"]: |
293 elif key in ["@exclude", "@exclude_match"]: |
331 self.__exclude.append(GreaseMonkeyUrlMatcher(value)) |
294 self.__exclude.append(value) |
332 |
295 |
333 elif key == "@require": |
296 elif key == "@require": |
334 requireList.append(value) |
297 requireList.append(value) |
335 |
298 |
336 elif key == "@run-at": |
299 elif key == "@run-at": |
337 if value == "document-end": |
300 if value == "document-end": |
338 self.__startAt = GreaseMonkeyScript.DocumentEnd |
301 self.__startAt = GreaseMonkeyScript.DocumentEnd |
339 elif value == "document-start": |
302 elif value == "document-start": |
340 self.__startAt = GreaseMonkeyScript.DocumentStart |
303 self.__startAt = GreaseMonkeyScript.DocumentStart |
|
304 elif value == "document-idle": |
|
305 self.__startAt = GreaseMonkeyScript.DocumentIdle |
341 |
306 |
342 elif key == "@downloadURL" and self.__downloadUrl.isEmpty(): |
307 elif key == "@downloadURL" and self.__downloadUrl.isEmpty(): |
343 self.__downloadUrl = QUrl(value) |
308 self.__downloadUrl = QUrl(value) |
344 |
309 |
345 elif key == "@updateURL" and self.__updateUrl.isEmpty(): |
310 elif key == "@updateURL" and self.__updateUrl.isEmpty(): |
346 self.__updateUrl = QUrl(value) |
311 self.__updateUrl = QUrl(value) |
347 |
312 |
348 if not self.__include: |
313 if not self.__include: |
349 self.__include.append(GreaseMonkeyUrlMatcher("*")) |
314 self.__include.append("*") |
350 |
|
351 marker = "// ==/UserScript==" |
|
352 index = fileData.find(marker) + len(marker) |
|
353 self.__metaData = fileData[:index] |
|
354 script = fileData[index:].strip() |
|
355 |
315 |
356 nspace = bytes(QCryptographicHash.hash( |
316 nspace = bytes(QCryptographicHash.hash( |
357 QByteArray(self.fullName().encode("utf-8")), |
317 QByteArray(self.fullName().encode("utf-8")), |
358 QCryptographicHash.Md4).toHex()).decode("ascii") |
318 QCryptographicHash.Md4).toHex()).decode("ascii") |
359 valuesScript = values_js.format(nspace) |
319 valuesScript = values_js.format(nspace) |
360 self.__script = "(function(){{{0}\n{1}\n{2}\n}})();".format( |
320 runCheck = """ |
361 valuesScript, self.__manager.requireScripts(requireList), script |
321 for (var value of {0}) {{ |
|
322 var re = new RegExp(value); |
|
323 if (re.test(window.location.href)) {{ |
|
324 return; |
|
325 }} |
|
326 }} |
|
327 __eric_includes = false; |
|
328 for (var value of {1}) {{ |
|
329 var re = new RegExp(value); |
|
330 if (re.test(window.location.href)) {{ |
|
331 __eric_includes = true; |
|
332 break; |
|
333 }} |
|
334 }} |
|
335 if (!__eric_includes) {{ |
|
336 return; |
|
337 }} |
|
338 delete __eric_includes;""".format( |
|
339 self.__toJavaScriptList(self.__exclude[:]), |
|
340 self.__toJavaScriptList(self.__include[:]) |
|
341 ) |
|
342 self.__script = "(function(){{{0}\n{1}\n{2}\n{3}\n}})();".format( |
|
343 runCheck, valuesScript, |
|
344 self.__manager.requireScripts(requireList), fileData |
362 ) |
345 ) |
363 self.__valid = True |
346 self.__valid = True |
364 |
347 |
365 def webScript(self): |
348 def webScript(self): |
366 """ |
349 """ |
367 Public method to create a script object. |
350 Public method to create a script object. |
368 |
351 |
369 @return prepared script object |
352 @return prepared script object |
370 @rtype QWebEngineScript |
353 @rtype QWebEngineScript |
371 """ |
354 """ |
|
355 if self.startAt() == GreaseMonkeyScript.DocumentStart: |
|
356 injectionPoint = QWebEngineScript.DocumentCreation |
|
357 elif self.startAt() == GreaseMonkeyScript.DocumentEnd: |
|
358 injectionPoint = QWebEngineScript.DocumentReady |
|
359 elif self.startAt() == GreaseMonkeyScript.DocumentIdle: |
|
360 injectionPoint = QWebEngineScript.Deferred |
|
361 else: |
|
362 raise ValueError("Wrong script start point.") |
|
363 |
372 script = QWebEngineScript() |
364 script = QWebEngineScript() |
373 script.setName(self.fullName()) |
365 script.setName(self.fullName()) |
374 if self.startAt() == GreaseMonkeyScript.DocumentStart: |
366 script.setInjectionPoint(injectionPoint) |
375 script.setInjectionPoint(QWebEngineScript.DocumentCreation) |
|
376 else: |
|
377 script.setInjectionPoint(QWebEngineScript.DocumentReady) |
|
378 script.setWorldId(QWebEngineScript.MainWorld) |
367 script.setWorldId(QWebEngineScript.MainWorld) |
379 script.setRunsOnSubFrames(not self.__noFrames) |
368 script.setRunsOnSubFrames(not self.__noFrames) |
380 script.setSourceCode("{0}\n{1}\n{2}".format( |
369 script.setSourceCode("{0}\n{1}".format( |
381 self.__metaData, bootstrap_js, self.__script |
370 bootstrap_js, self.__script |
382 )) |
371 )) |
383 return script |
372 return script |
|
373 |
|
374 def __toJavaScriptList(self, patterns): |
|
375 """ |
|
376 Private method to convert a list of str to a string containing a valid |
|
377 JavaScript list definition. |
|
378 |
|
379 @param patterns list of match patterns |
|
380 @type list of str |
|
381 @return JavaScript script containing the list |
|
382 @rtype str |
|
383 """ |
|
384 patternList = [] |
|
385 for pattern in patterns: |
|
386 if pattern.startswith("/") and pattern.endswith("/") and \ |
|
387 len(pattern) > 1: |
|
388 pattern = pattern[1:-1] |
|
389 else: |
|
390 pattern = pattern.replace(".", "\\.").replace("*", ".*") |
|
391 pattern = "'{0}'".format(pattern) |
|
392 patternList.append(pattern) |
|
393 |
|
394 script = "[{0}]".format(",".join(patternList)) |
|
395 return script |