eric6/Helpviewer/GreaseMonkey/GreaseMonkeyScript.py

branch
maintenance
changeset 7286
7eb04391adf7
parent 7226
babe80d84a3e
parent 7285
1ff497f33f31
child 7287
1c17f2191bdd
equal deleted inserted replaced
7226:babe80d84a3e 7286:7eb04391adf7
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2012 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the GreaseMonkey script.
8 """
9
10 from __future__ import unicode_literals
11
12 from PyQt5.QtCore import QUrl, QRegExp
13
14 from .GreaseMonkeyUrlMatcher import GreaseMonkeyUrlMatcher
15
16
17 class GreaseMonkeyScript(object):
18 """
19 Class implementing the GreaseMonkey script.
20 """
21 DocumentStart = 0
22 DocumentEnd = 1
23
24 def __init__(self, manager, path):
25 """
26 Constructor
27
28 @param manager reference to the manager object (GreaseMonkeyManager)
29 @param path path of the Javascript file (string)
30 """
31 self.__manager = manager
32
33 self.__name = ""
34 self.__namespace = "GreaseMonkeyNS"
35 self.__description = ""
36 self.__version = ""
37
38 self.__include = []
39 self.__exclude = []
40
41 self.__downloadUrl = QUrl()
42 self.__startAt = GreaseMonkeyScript.DocumentEnd
43
44 self.__script = ""
45 self.__fileName = path
46 self.__enabled = True
47 self.__valid = False
48
49 self.__parseScript(path)
50
51 def isValid(self):
52 """
53 Public method to check the validity of the script.
54
55 @return flag indicating a valid script (boolean)
56 """
57 return self.__valid
58
59 def name(self):
60 """
61 Public method to get the name of the script.
62
63 @return name of the script (string)
64 """
65 return self.__name
66
67 def nameSpace(self):
68 """
69 Public method to get the name space of the script.
70
71 @return name space of the script (string)
72 """
73 return self.__namespace
74
75 def fullName(self):
76 """
77 Public method to get the full name of the script.
78
79 @return full name of the script (string)
80 """
81 return "{0}/{1}".format(self.__namespace, self.__name)
82
83 def description(self):
84 """
85 Public method to get the description of the script.
86
87 @return description of the script (string)
88 """
89 return self.__description
90
91 def version(self):
92 """
93 Public method to get the version of the script.
94
95 @return version of the script (string)
96 """
97 return self.__version
98
99 def downloadUrl(self):
100 """
101 Public method to get the download URL of the script.
102
103 @return download URL of the script (QUrl)
104 """
105 return QUrl(self.__downloadUrl)
106
107 def startAt(self):
108 """
109 Public method to get the start point of the script.
110
111 @return start point of the script (DocumentStart or DocumentEnd)
112 """
113 return self.__startAt
114
115 def isEnabled(self):
116 """
117 Public method to check, if the script is enabled.
118
119 @return flag indicating an enabled state (boolean)
120 """
121 return self.__enabled
122
123 def setEnabled(self, enable):
124 """
125 Public method to enable a script.
126
127 @param enable flag indicating the new enabled state (boolean)
128 """
129 self.__enabled = enable
130
131 def include(self):
132 """
133 Public method to get the list of included URLs.
134
135 @return list of included URLs (list of strings)
136 """
137 urlList = []
138 for matcher in self.__include:
139 urlList.append(matcher.pattern())
140 return urlList
141
142 def exclude(self):
143 """
144 Public method to get the list of excluded URLs.
145
146 @return list of excluded URLs (list of strings)
147 """
148 urlList = []
149 for matcher in self.__exclude:
150 urlList.append(matcher.pattern())
151 return urlList
152
153 def script(self):
154 """
155 Public method to get the Javascript source.
156
157 @return Javascript source (string)
158 """
159 return self.__script
160
161 def fileName(self):
162 """
163 Public method to get the path of the Javascript file.
164
165 @return path path of the Javascript file (string)
166 """
167 return self.__fileName
168
169 def match(self, urlString):
170 """
171 Public method to check, if the script matches the given URL.
172
173 @param urlString URL (string)
174 @return flag indicating a match (boolean)
175 """
176 if not self.__enabled:
177 return False
178
179 for matcher in self.__exclude:
180 if matcher.match(urlString):
181 return False
182
183 for matcher in self.__include:
184 if matcher.match(urlString):
185 return True
186
187 return False
188
189 def __parseScript(self, path):
190 """
191 Private method to parse the given script and populate the data
192 structure.
193
194 @param path path of the Javascript file (string)
195 """
196 try:
197 f = open(path, "r", encoding="utf-8")
198 fileData = f.read()
199 f.close()
200 except (IOError, OSError):
201 # silently ignore because it shouldn't happen
202 return
203
204 rx = QRegExp("// ==UserScript==(.*)// ==/UserScript==")
205 rx.indexIn(fileData)
206 metaDataBlock = rx.cap(1).strip()
207
208 if metaDataBlock == "":
209 # invalid script file
210 return
211
212 requireList = []
213 for line in metaDataBlock.splitlines():
214 if not line.startswith("// @"):
215 continue
216
217 line = line[3:].replace("\t", " ")
218 index = line.find(" ")
219 if index < 0:
220 continue
221
222 key = line[:index].strip()
223 value = line[index + 1:].strip()
224
225 # Ignored values: @resource, @unwrap
226
227 if not key or not value:
228 continue
229
230 if key == "@name":
231 self.__name = value
232
233 elif key == "@namespace":
234 self.__namespace = value
235
236 elif key == "@description":
237 self.__description = value
238
239 elif key == "@version":
240 self.__version = value
241
242 elif key == "@updateURL":
243 self.__downloadUrl = QUrl(value)
244
245 elif key in ["@include", "@match"]:
246 self.__include.append(GreaseMonkeyUrlMatcher(value))
247
248 elif key in ["@exclude", "@exclude_match"]:
249 self.__exclude.append(GreaseMonkeyUrlMatcher(value))
250
251 elif key == "@require":
252 requireList.append(value)
253
254 elif key == "@run-at":
255 if value == "document-end":
256 self.__startAt = GreaseMonkeyScript.DocumentEnd
257 elif value == "document-start":
258 self.__startAt = GreaseMonkeyScript.DocumentStart
259
260 elif key == "@downloadURL" and self.__downloadUrl.isEmpty():
261 self.__downloadUrl = QUrl(value)
262
263 if not self.__include:
264 self.__include.append(GreaseMonkeyUrlMatcher("*"))
265
266 marker = "// ==/UserScript=="
267 index = fileData.find(marker) + len(marker)
268 script = fileData[index:].strip()
269 script = "{0}{1}".format(
270 self.__manager.requireScripts(requireList),
271 script)
272 self.__script = "(function(){{{0}}})();".format(script)
273 self.__valid = len(script) > 0

eric ide

mercurial