25 |
25 |
26 @return script to setup the web channel |
26 @return script to setup the web channel |
27 @rtype str |
27 @rtype str |
28 """ |
28 """ |
29 source = """ |
29 source = """ |
30 (function() {{ |
30 (function() {{ |
31 {0} |
31 {0} |
32 |
32 |
33 function registerExternal(e) {{ |
33 function registerExternal(e) {{ |
34 window.external = e; |
34 window.external = e; |
35 if (window.external) {{ |
35 if (window.external) {{ |
36 var event = document.createEvent('Event'); |
36 var event = document.createEvent('Event'); |
37 event.initEvent('_eric_external_created', true, true); |
37 event.initEvent('_eric_external_created', true, true); |
38 document.dispatchEvent(event); |
38 document.dispatchEvent(event); |
|
39 }} |
|
40 }} |
|
41 |
|
42 if (self !== top) {{ |
|
43 if (top.external) |
|
44 registerExternal(top.external); |
|
45 else |
|
46 top.document.addEventListener( |
|
47 '_eric_external_created', function() {{ |
|
48 registerExternal(top.external); |
|
49 }}); |
|
50 return; |
|
51 }} |
|
52 |
|
53 function registerWebChannel() {{ |
|
54 try {{ |
|
55 new QWebChannel(qt.webChannelTransport, function(channel) {{ |
|
56 registerExternal(channel.objects.eric_object); |
|
57 var external = channel.objects.eric_object; |
|
58 external.extra = {{}}; |
|
59 for (var key in channel.objects) {{ |
|
60 if (key != 'eric_object' && key.startsWith('eric_')) {{ |
|
61 external.extra[key.substr(3)] = channel.objects[key]; |
|
62 }} |
39 }} |
63 }} |
40 }} |
64 registerExternal(external); |
41 |
65 }}); |
42 if (self !== top) {{ |
66 }} catch (e) {{ |
43 if (top.external) |
67 setTimeout(registerWebChannel, 100); |
44 registerExternal(top.external); |
68 }} |
45 else |
69 }} |
46 top.document.addEventListener( |
70 registerWebChannel(); |
47 '_eric_external_created', function() {{ |
71 |
48 registerExternal(top.external); |
72 }})()""" |
49 }}); |
|
50 return; |
|
51 }} |
|
52 |
|
53 function registerWebChannel() {{ |
|
54 try {{ |
|
55 new QWebChannel(qt.webChannelTransport, function(channel) {{ |
|
56 registerExternal(channel.objects.eric_object); |
|
57 }}); |
|
58 }} catch (e) {{ |
|
59 setTimeout(registerWebChannel, 100); |
|
60 }} |
|
61 }} |
|
62 registerWebChannel(); |
|
63 |
|
64 }})()""" |
|
65 |
73 |
66 return source.format(readAllFileContents(":/javascript/qwebchannel.js")) |
74 return source.format(readAllFileContents(":/javascript/qwebchannel.js")) |
67 |
75 |
68 |
76 |
69 def setStyleSheet(css): |
77 def setStyleSheet(css): |
95 @type QPoint |
103 @type QPoint |
96 @return script to extract form data |
104 @return script to extract form data |
97 @rtype str |
105 @rtype str |
98 """ |
106 """ |
99 source = """ |
107 source = """ |
100 (function() {{ |
108 (function() {{ |
101 var e = document.elementFromPoint({0}, {1}); |
109 var e = document.elementFromPoint({0}, {1}); |
102 if (!e || e.tagName != 'INPUT') |
110 if (!e || e.tagName != 'INPUT') |
103 return; |
111 return; |
104 var fe = e.parentElement; |
112 var fe = e.parentElement; |
105 while (fe) {{ |
113 while (fe) {{ |
106 if (fe.tagName == 'FORM') |
114 if (fe.tagName == 'FORM') |
107 break; |
115 break; |
108 fe = fe.parentElement; |
116 fe = fe.parentElement; |
109 }} |
117 }} |
110 if (!fe) |
118 if (!fe) |
111 return; |
119 return; |
112 var res = {{ |
120 var res = {{ |
113 method: fe.method.toLowerCase(), |
121 method: fe.method.toLowerCase(), |
114 action: fe.action, |
122 action: fe.action, |
115 inputName: e.name, |
123 inputName: e.name, |
116 inputs: [], |
124 inputs: [], |
117 }}; |
125 }}; |
118 for (var i = 0; i < fe.length; ++i) {{ |
126 for (var i = 0; i < fe.length; ++i) {{ |
119 var input = fe.elements[i]; |
127 var input = fe.elements[i]; |
120 res.inputs.push([input.name, input.value]); |
128 res.inputs.push([input.name, input.value]); |
121 }} |
129 }} |
122 return res; |
130 return res; |
123 }})()""" |
131 }})()""" |
124 return source.format(pos.x(), pos.y()) |
132 return source.format(pos.x(), pos.y()) |
125 |
133 |
126 |
134 |
127 def getAllImages(): |
135 def getAllImages(): |
128 """ |
136 """ |
207 @type QByteArray |
215 @type QByteArray |
208 @return script to send Post data |
216 @return script to send Post data |
209 @rtype str |
217 @rtype str |
210 """ |
218 """ |
211 source = """ |
219 source = """ |
212 (function() {{ |
220 (function() {{ |
213 var form = document.createElement('form'); |
221 var form = document.createElement('form'); |
214 form.setAttribute('method', 'POST'); |
222 form.setAttribute('method', 'POST'); |
215 form.setAttribute('action', '{0}'); |
223 form.setAttribute('action', '{0}'); |
216 var val; |
224 var val; |
217 {1} |
225 {1} |
218 form.submit(); |
226 form.submit(); |
219 }})()""" |
227 }})()""" |
220 |
228 |
221 valueSource = """ |
229 valueSource = """ |
222 val = document.createElement('input'); |
230 val = document.createElement('input'); |
223 val.setAttribute('type', 'hidden'); |
231 val.setAttribute('type', 'hidden'); |
224 val.setAttribute('name', '{0}'); |
232 val.setAttribute('name', '{0}'); |
225 val.setAttribute('value', '{1}'); |
233 val.setAttribute('value', '{1}'); |
226 form.appendChild(val);""" |
234 form.appendChild(val);""" |
227 |
235 |
228 values = "" |
236 values = "" |
229 query = QUrlQuery(data) |
237 query = QUrlQuery(data) |
230 for name, value in query.queryItems(QUrl.FullyDecoded): |
238 for name, value in query.queryItems(QUrl.FullyDecoded): |
231 value = value.replace("'", "\\'") |
239 value = value.replace("'", "\\'") |
241 |
249 |
242 @return script to monitor a web page |
250 @return script to monitor a web page |
243 @rtype str |
251 @rtype str |
244 """ |
252 """ |
245 source = """ |
253 source = """ |
246 (function() { |
254 (function() { |
247 function findUsername(inputs) { |
255 function findUsername(inputs) { |
248 var usernameNames = ['user', 'name', 'login']; |
256 var usernameNames = ['user', 'name', 'login']; |
249 for (var i = 0; i < usernameNames.length; ++i) { |
257 for (var i = 0; i < usernameNames.length; ++i) { |
250 for (var j = 0; j < inputs.length; ++j) |
258 for (var j = 0; j < inputs.length; ++j) |
251 if (inputs[j].type == 'text' && |
259 if (inputs[j].type == 'text' && |
252 inputs[j].value.length && |
260 inputs[j].value.length && |
253 inputs[j].name.indexOf(usernameNames[i]) != -1) |
261 inputs[j].name.indexOf(usernameNames[i]) != -1) |
254 return inputs[j].value; |
262 return inputs[j].value; |
255 } |
263 } |
256 for (var i = 0; i < inputs.length; ++i) |
264 for (var i = 0; i < inputs.length; ++i) |
257 if (inputs[i].type == 'text' && inputs[i].value.length) |
265 if (inputs[i].type == 'text' && inputs[i].value.length) |
258 return inputs[i].value; |
266 return inputs[i].value; |
259 for (var i = 0; i < inputs.length; ++i) |
267 for (var i = 0; i < inputs.length; ++i) |
260 if (inputs[i].type == 'email' && inputs[i].value.length) |
268 if (inputs[i].type == 'email' && inputs[i].value.length) |
261 return inputs[i].value; |
269 return inputs[i].value; |
262 return ''; |
270 return ''; |
|
271 } |
|
272 |
|
273 function registerForm(form) { |
|
274 form.addEventListener('submit', function() { |
|
275 var form = this; |
|
276 var data = ''; |
|
277 var password = ''; |
|
278 var inputs = form.getElementsByTagName('input'); |
|
279 for (var i = 0; i < inputs.length; ++i) { |
|
280 var input = inputs[i]; |
|
281 var type = input.type.toLowerCase(); |
|
282 if (type != 'text' && type != 'password' && |
|
283 type != 'email') |
|
284 continue; |
|
285 if (!password && type == 'password') |
|
286 password = input.value; |
|
287 data += encodeURIComponent(input.name); |
|
288 data += '='; |
|
289 data += encodeURIComponent(input.value); |
|
290 data += '&'; |
263 } |
291 } |
264 |
292 if (!password) |
265 function registerForm(form) { |
293 return; |
266 form.addEventListener('submit', function() { |
294 data = data.substring(0, data.length - 1); |
267 var form = this; |
295 var url = window.location.href; |
268 var data = ''; |
296 var username = findUsername(inputs); |
269 var password = ''; |
297 external.passwordManager.formSubmitted( |
270 var inputs = form.getElementsByTagName('input'); |
298 url, username, password, data); |
271 for (var i = 0; i < inputs.length; ++i) { |
299 }, true); |
272 var input = inputs[i]; |
300 } |
273 var type = input.type.toLowerCase(); |
301 |
274 if (type != 'text' && type != 'password' && |
302 for (var i = 0; i < document.forms.length; ++i) |
275 type != 'email') |
303 registerForm(document.forms[i]); |
276 continue; |
304 |
277 if (!password && type == 'password') |
305 var observer = new MutationObserver(function(mutations) { |
278 password = input.value; |
306 for (var i = 0; i < mutations.length; ++i) |
279 data += encodeURIComponent(input.name); |
307 for (var j = 0; j < mutations[i].addedNodes.length; ++j) |
280 data += '='; |
308 if (mutations[i].addedNodes[j].tagName == 'FORM') |
281 data += encodeURIComponent(input.value); |
309 registerForm(mutations[i].addedNodes[j]); |
282 data += '&'; |
310 }); |
283 } |
311 observer.observe(document.documentElement, { |
284 if (!password) |
312 childList: true, subtree: true |
285 return; |
313 }); |
286 data = data.substring(0, data.length - 1); |
314 |
287 var url = window.location.href; |
315 })()""" |
288 var username = findUsername(inputs); |
|
289 external.passwordManager.formSubmitted( |
|
290 url, username, password, data); |
|
291 }, true); |
|
292 } |
|
293 |
|
294 for (var i = 0; i < document.forms.length; ++i) |
|
295 registerForm(document.forms[i]); |
|
296 |
|
297 var observer = new MutationObserver(function(mutations) { |
|
298 for (var i = 0; i < mutations.length; ++i) |
|
299 for (var j = 0; j < mutations[i].addedNodes.length; ++j) |
|
300 if (mutations[i].addedNodes[j].tagName == 'FORM') |
|
301 registerForm(mutations[i].addedNodes[j]); |
|
302 }); |
|
303 observer.observe(document.documentElement, { |
|
304 childList: true, subtree: true |
|
305 }); |
|
306 |
|
307 })()""" |
|
308 return source |
316 return source |
309 |
317 |
310 |
318 |
311 def completeFormData(data): |
319 def completeFormData(data): |
312 """ |
320 """ |
316 @type QByteArray |
324 @type QByteArray |
317 @return script to fill a form |
325 @return script to fill a form |
318 @rtype str |
326 @rtype str |
319 """ |
327 """ |
320 source = """ |
328 source = """ |
321 (function() {{ |
329 (function() {{ |
322 var data = '{0}'.split('&'); |
330 var data = '{0}'.split('&'); |
323 var inputs = document.getElementsByTagName('input'); |
331 var inputs = document.getElementsByTagName('input'); |
324 |
332 |
325 for (var i = 0; i < data.length; ++i) {{ |
333 for (var i = 0; i < data.length; ++i) {{ |
326 var pair = data[i].split('='); |
334 var pair = data[i].split('='); |
327 if (pair.length != 2) |
335 if (pair.length != 2) |
328 continue; |
336 continue; |
329 var key = decodeURIComponent(pair[0]); |
337 var key = decodeURIComponent(pair[0]); |
330 var val = decodeURIComponent(pair[1]); |
338 var val = decodeURIComponent(pair[1]); |
331 for (var j = 0; j < inputs.length; ++j) {{ |
339 for (var j = 0; j < inputs.length; ++j) {{ |
332 var input = inputs[j]; |
340 var input = inputs[j]; |
333 var type = input.type.toLowerCase(); |
341 var type = input.type.toLowerCase(); |
334 if (type != 'text' && type != 'password' && |
342 if (type != 'text' && type != 'password' && |
335 type != 'email') |
343 type != 'email') |
336 continue; |
344 continue; |
337 if (input.name == key) |
345 if (input.name == key) |
338 input.value = val; |
346 input.value = val; |
339 }} |
347 }} |
340 }} |
348 }} |
341 |
349 |
342 }})()""" |
350 }})()""" |
343 |
351 |
344 data = bytes(data).decode("utf-8") |
352 data = bytes(data).decode("utf-8") |
345 data = data.replace("'", "\\'") |
353 data = data.replace("'", "\\'") |
346 return source.format(data) |
354 return source.format(data) |
347 |
355 |
354 @type str |
362 @type str |
355 @return script to set the style sheet |
363 @return script to set the style sheet |
356 @rtype str |
364 @rtype str |
357 """ |
365 """ |
358 source = """ |
366 source = """ |
359 (function() {{ |
367 (function() {{ |
360 var css = document.createElement('style'); |
368 var css = document.createElement('style'); |
361 css.setAttribute('type', 'text/css'); |
369 css.setAttribute('type', 'text/css'); |
362 css.appendChild(document.createTextNode('{0}')); |
370 css.appendChild(document.createTextNode('{0}')); |
363 document.getElementsByTagName('head')[0].appendChild(css); |
371 document.getElementsByTagName('head')[0].appendChild(css); |
364 }})()""" |
372 }})()""" |
365 style = css.replace("'", "\\'").replace("\n", "\\n") |
373 style = css.replace("'", "\\'").replace("\n", "\\n") |
366 return source.format(style) |
374 return source.format(style) |
367 |
375 |
368 ########################################################################### |
376 ########################################################################### |
369 ## scripts below are specific for eric |
377 ## scripts below are specific for eric |