Tue, 13 Feb 2018 19:59:44 +0100
Fixed a few code style issues.
# -*- coding: utf-8 -*- # Copyright (c) 2016 - 2018 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module containing function to generate JavaScript code. """ # # This code was ported from QupZilla. # Copyright (C) David Rosca <nowrep@gmail.com> # from __future__ import unicode_literals from PyQt5.QtCore import QUrlQuery, QUrl from .WebBrowserTools import readAllFileContents def setupWebChannel(worldId): """ Function generating a script to setup the web channel. @param worldId world ID for which to setup the channel @type int @return script to setup the web channel @rtype str """ source = """ // ==UserScript== {0} // ==/UserScript== (function() {{ {1} function registerExternal(e) {{ window.external = e; if (window.external) {{ var event = document.createEvent('Event'); event.initEvent('_eric_external_created', true, true); window._eric_external = true; document.dispatchEvent(event); }} }} if (self !== top) {{ if (top._eric_external) registerExternal(top.external); else top.document.addEventListener( '_eric_external_created', function() {{ registerExternal(top.external); }}); return; }} function registerWebChannel() {{ try {{ new QWebChannel(qt.webChannelTransport, function(channel) {{ var external = channel.objects.eric_object; external.extra = {{}}; for (var key in channel.objects) {{ if (key != 'eric_object' && key.startsWith('eric_')) {{ external.extra[key.substr(5)] = channel.objects[key]; }} }} registerExternal(external); }}); }} catch (e) {{ setTimeout(registerWebChannel, 100); }} }} registerWebChannel(); }})()""" from WebBrowser.WebBrowserPage import WebBrowserPage if worldId == WebBrowserPage.SafeJsWorld: match = "// @exclude eric:*" else: match = "// @include eric:*" return source.format( match, readAllFileContents(":/javascript/qwebchannel.js")) def setupWindowObject(): """ Function generating a script to setup window.object add-ons. @return generated script @rtype str """ source = """ (function() { var external = {}; window.external = external; window.print = function() { window.location = 'eric:PrintPage'; }; })()""" return source def setStyleSheet(css): """ Function generating a script to set a user style sheet. @param css style sheet to be applied @type str @return script to set a user style sheet @rtype str """ source = """ (function() {{ var css = document.createElement('style'); css.setAttribute('type', 'text/css'); css.appendChild(document.createTextNode('{0}')); document.getElementsByTagName('head')[0].appendChild(css); }})()""" style = css.replace("'", "\\'").replace("\n", "\\n") return source.format(style) def getFormData(pos): """ Function generating a script to extract data for a form element. @param pos position to extract data at @type QPoint @return script to extract form data @rtype str """ source = """ (function() {{ var e = document.elementFromPoint({0}, {1}); if (!e || e.tagName != 'INPUT') return; var fe = e.parentElement; while (fe) {{ if (fe.tagName == 'FORM') break; fe = fe.parentElement; }} if (!fe) return; var res = {{ method: fe.method.toLowerCase(), action: fe.action, inputName: e.name, inputs: [], }}; for (var i = 0; i < fe.length; ++i) {{ var input = fe.elements[i]; res.inputs.push([input.name, input.value]); }} return res; }})()""" return source.format(pos.x(), pos.y()) def getAllImages(): """ Function generating a script to extract all image tags of a web page. @return script to extract image tags @rtype str """ source = """ (function() { var out = []; var imgs = document.getElementsByTagName('img'); for (var i = 0; i < imgs.length; ++i) { var e = imgs[i]; out.push({ src: e.src, alt: e.alt }); } return out; })()""" return source def getAllMetaAttributes(): """ Function generating a script to extract all meta attributes of a web page. @return script to extract meta attributes @rtype str """ source = """ (function() { var out = []; var meta = document.getElementsByTagName('meta'); for (var i = 0; i < meta.length; ++i) { var e = meta[i]; out.push({ name: e.getAttribute('name'), content: e.getAttribute('content'), httpequiv: e.getAttribute('http-equiv'), charset: e.getAttribute('charset') }); } return out; })()""" return source def getOpenSearchLinks(): """ Function generating a script to extract all open search links. @return script to extract all open serach links @rtype str """ source = """ (function() { var out = []; var links = document.getElementsByTagName('link'); for (var i = 0; i < links.length; ++i) { var e = links[i]; if (e.type == 'application/opensearchdescription+xml') { out.push({ url: e.getAttribute('href'), title: e.getAttribute('title') }); } } return out; })()""" return source def sendPostData(url, data): """ Function generating a script to send Post data. @param url URL to send the data to @type QUrl @param data data to be sent @type QByteArray @return script to send Post data @rtype str """ source = """ (function() {{ var form = document.createElement('form'); form.setAttribute('method', 'POST'); form.setAttribute('action', '{0}'); var val; {1} form.submit(); }})()""" valueSource = """ val = document.createElement('input'); val.setAttribute('type', 'hidden'); val.setAttribute('name', '{0}'); val.setAttribute('value', '{1}'); form.appendChild(val);""" values = "" query = QUrlQuery(data) for name, value in query.queryItems(QUrl.FullyDecoded): value = value.replace("'", "\\'") name = name.replace("'", "\\'") values += valueSource.format(name, value) return source.format(url.toString(), values) def setupFormObserver(): """ Function generating a script to monitor a web form for user entries. @return script to monitor a web page @rtype str """ source = """ (function() { function findUsername(inputs) { var usernameNames = ['user', 'name', 'login']; for (var i = 0; i < usernameNames.length; ++i) { for (var j = 0; j < inputs.length; ++j) if (inputs[j].type == 'text' && inputs[j].value.length && inputs[j].name.indexOf(usernameNames[i]) != -1) return inputs[j].value; } for (var i = 0; i < inputs.length; ++i) if (inputs[i].type == 'text' && inputs[i].value.length) return inputs[i].value; for (var i = 0; i < inputs.length; ++i) if (inputs[i].type == 'email' && inputs[i].value.length) return inputs[i].value; return ''; } function registerForm(form) { form.addEventListener('submit', function() { var form = this; var data = ''; var password = ''; var inputs = form.getElementsByTagName('input'); for (var i = 0; i < inputs.length; ++i) { var input = inputs[i]; var type = input.type.toLowerCase(); if (type != 'text' && type != 'password' && type != 'email') continue; if (!password && type == 'password') password = input.value; data += encodeURIComponent(input.name); data += '='; data += encodeURIComponent(input.value); data += '&'; } if (!password) return; data = data.substring(0, data.length - 1); var url = window.location.href; var username = findUsername(inputs); external.passwordManager.formSubmitted( url, username, password, data); }, true); } for (var i = 0; i < document.forms.length; ++i) registerForm(document.forms[i]); var observer = new MutationObserver(function(mutations) { for (var i = 0; i < mutations.length; ++i) for (var j = 0; j < mutations[i].addedNodes.length; ++j) if (mutations[i].addedNodes[j].tagName == 'FORM') registerForm(mutations[i].addedNodes[j]); }); observer.observe(document.documentElement, { childList: true, subtree: true }); })()""" return source def completeFormData(data): """ Function generating a script to fill in form data. @param data data to be filled into the form @type QByteArray @return script to fill a form @rtype str """ source = """ (function() {{ var data = '{0}'.split('&'); var inputs = document.getElementsByTagName('input'); for (var i = 0; i < data.length; ++i) {{ var pair = data[i].split('='); if (pair.length != 2) continue; var key = decodeURIComponent(pair[0]); var val = decodeURIComponent(pair[1]); for (var j = 0; j < inputs.length; ++j) {{ var input = inputs[j]; var type = input.type.toLowerCase(); if (type != 'text' && type != 'password' && type != 'email') continue; if (input.name == key) input.value = val; }} }} }})()""" data = bytes(data).decode("utf-8") data = data.replace("'", "\\'") return source.format(data) def setCss(css): """ Function generating a script to set a given CSS style sheet. @param css style sheet @type str @return script to set the style sheet @rtype str """ source = """ (function() {{ var css = document.createElement('style'); css.setAttribute('type', 'text/css'); css.appendChild(document.createTextNode('{0}')); document.getElementsByTagName('head')[0].appendChild(css); }})()""" style = css.replace("'", "\\'").replace("\n", "\\n") return source.format(style) ########################################################################### ## scripts below are specific for eric ########################################################################### def getFeedLinks(): """ Function generating a script to extract all RSS and Atom feed links. @return script to extract all RSS and Atom feed links @rtype str """ source = """ (function() { var out = []; var links = document.getElementsByTagName('link'); for (var i = 0; i < links.length; ++i) { var e = links[i]; if ((e.rel == 'alternate') && ((e.type == 'application/atom+xml') || (e.type == 'application/rss+xml') ) ) { out.push({ url: e.getAttribute('href'), title: e.getAttribute('title') }); } } return out; })()""" return source