Как подключиться к UserContentManager «скрипт-сообщение-получено» из Python, Javascript? - PullRequest
0 голосов
/ 01 мая 2018

Как мне подключиться к WebKit2.UserContentManager «скрипт-сообщение-получено» от Python, Javascript? Я бился головой о «стену» в течение нескольких дней, пытаясь понять это. Я пытаюсь заставить UserContentManager вернуть весь документ, а также элементы, на которые я нажимаю. Любая помощь будет оценена, спасибо. Вот исполняемый код:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Python imports
import sys

# Gtk imports
try:
    import gi
    gi.require_version('Gtk', '3.0')
    gi.require_version('WebKit2', '4.0')
    gi.require_version('WebKit2WebExtension', '4.0')
    #gi.repository.WebKit2WebExtension
    from gi.repository import Gtk, WebKit2
    #from gi.repository import WebKit2WebExtension
except:
    sys.exit("This script requires Gtk 3.0 or newer,"
                            + " and WebKit2 4.0 or newer!")

GET_ELEMENT = '''
let ns = new XMLSerializer();
let elemDoc = "";
let wholeDoc = "";

document.addEventListener('click', function(e) {
    e = e || window.event;
    let target = e.target || e.srcElement;
    getEntry(target);
    }, false);

function getEntry(target) {
    el = target;
    tag = el.tagName.toLowerCase();
    while (tag != "entry") {
      el = el.parentNode;
      tag = el.tagName.toLowerCase();
      elemDoc = ns.serializeToString(el);
      };
//    window.webkit.messageHandlers.elemDoc.postMessage("elemDoc");
    console.log(elemDoc);
    };

function getDocument() {
    wholeDoc = ns.serializeToString(document);
//        TypeError: undefined is not an object (
//        evaluating 'window.webkit.messageHandlers.wholeDoc.postMessage')
//        window.webkit.messageHandlers.wholeDoc.postMessage("wholeDoc");

        console.log(wholeDoc);
//        return wholeDoc;
    };
'''


def get_content(v, param):
    ''''''
    # Get the wholeDoc
    #TODO editor = WebKit2WebExtension.WebEditor()
    #editor = WebKit2WebExtension.WebEditor()
    #print(editor)

    #TODO WebKit2WebExtension.WebEditor.signals.selection_changed(editor)
    #TODO WebKit2WebExtension.WebEditor.signals.get_page(editor)
    #page = WebKit2WebExtension.WebEditor().get_page()  # None
    #page = editor.get_page()  # None
    #print(page)
    #print(page.get_dom_document())

    #TODO WebKit2WebExtension.WebPage(**kwargs).get_editor()
    #TODO WebKit2WebExtension.WebPage(**kwargs).get_main_frame()

    #WebKit2WebExtension.WebEditor.get_page()
    #WebKit2WebExtension.WebPage.get_dom_document()

    #WebKit2WebExtension.WebPage.signals

    #WebKit2WebExtension.WebPage(**kwargs)

    #TODO This is working to get the wholeDoc in the Javascript console
    v.run_javascript("getDocument()")
    #print(v.run_javascript("""event.target ? event.target : null;"""))
    #FIXME Not returning wholeDoc to Python
    #result = v.run_javascript("getDocument()")
    #FIXME TypeError: Argument 1 does not allow None as a value
    #wholeDoc = v.run_javascript_finish(v)
    #FIXME Gio.AsyncResult
    #print('result: ', v.run_javascript_finish(v))
    #FIXME 'UserContentManager' object has no attribute 'signals'
    #FIXME Still, I have a problem connecting to script-message-received
    #wholeDoc = user_cont_man.signals.script_message_received(
        #user_cont_man, v.run_javascript("getDocument()"))
    #print('Python: ', wholeDoc)

    # Get the elemDoc
    #FIXME ReferenceError: Can't find variable: target
    #v.run_javascript("getEntry(target)")
    #elemDoc = v.run_javascript_finish()
    #print(elemDoc)

    return

w = Gtk.Window()
v = WebKit2.WebView()
sw = Gtk.ScrolledWindow()
w.add(sw)
sw.add(v)
w.set_size_request(500, 500)
w.connect("destroy", lambda q: Gtk.main_quit())
vset = v.get_settings()
vset.set_enable_write_console_messages_to_stdout(True)
user_cont_man = v.get_user_content_manager()

STYLE = '''entry { display:block;}
entry:hover { background-color:#729fcf; cursor:pointer;}
'''
style = WebKit2.UserStyleSheet.new(STYLE, 0, 1, None, None)
user_cont_man.add_style_sheet(style)

script = WebKit2.UserScript.new(GET_ELEMENT, 0, 1, None, None)
user_cont_man.add_script(script)

#FIXME Connect to the signals
#user_cont_man.connect("script-message-received::elemDoc",
    #get_content)  # , user_cont_man, None

user_cont_man.connect("script-message-received::wholeDoc",
    get_content)  # , user_cont_man, None

#FIXME Register the handlers
#user_cont_man.register_script_message_handler("elemDoc")

user_cont_man.register_script_message_handler("wholeDoc")

#TODO This is working to get the wholeDoc in the Javascript console
#FIXME Not returning wholeDoc to Python
v.connect("button-press-event", get_content)

v.load_html("""<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="dictstyle.css" type="text/css"?>
<!DOCTYPE TEI SYSTEM "somedefinition.dtd" >
<TEI>
    <teiHeader>
        <fileDesc>
            <titleStmt>
                <title>SomeDictionary TEI file</title>
            </titleStmt>
        </fileDesc>
    </teiHeader>
    <text>
        <body>
            <divGen>A</divGen>
            <div id="selector">
                <entry id="0">
                    <form source="someone">
                        <orth>word_0</orth>
                        <pron />
                    </form>
                </entry>
                <entry id="1">
                    <form source="someone">
                        <orth>word_1</orth>
                        <pron />
                    </form>
                </entry>
                <entry id="2">
                    <form source="someone">
                        <orth>word_2</orth>
                        <pron />
                    </form>
                </entry>
                <entry id="3">
                    <form source="someone">
                        <orth>word_3</orth>
                        <pron />
                    </form>
                </entry>
                <entry id="4">
                    <form source="someone">
                        <orth>word_4</orth>
                        <pron />
                    </form>
                </entry>
                <entry id="5">
                    <form source="someone">
                        <orth>word_5</orth>
                        <pron />
                    </form>
                </entry>
                <entry id="6">
                    <form source="someone">
                        <orth>word_6</orth>
                        <pron />
                    </form>
                </entry>
                <entry id="7">
                    <form source="someone">
                        <orth>word_7</orth>
                        <pron />
                    </form>
                </entry>
                <entry id="8">
                    <form source="someone">
                        <orth>word_8</orth>
                        <pron />
                    </form>
                </entry>
                <entry id="9">
                    <form source="someone">
                        <orth>word_9</orth>
                        <pron />
                    </form>
                </entry>
            </div>
        </body>
    </text>
</TEI>
""", "file:///")

w.show_all()
Gtk.main()

''' GetNativeBackend(self)

    Return the pointer to the native backend used by this control.

    This method can be used to retrieve the pointer to the native rendering
    engine used by this control. The return value needs to be down-casted
    to the appropriate type depending on the platform: under Windows, it’s
    a pointer to IWebBrowser2 interface, under OS X it’s a WebView pointer
    and under GTK it’s a WebKitWebView.'''
...