view enso_pyxpcom.py @ 3:21f5e1dc0a4c default tip

text selection for firefox will return the full contents of the current text field if no text is selected. also, the seldict contains references to the currently-focused element and window, if any.
author Atul Varma <varmaa@toolness.com>
date Fri, 09 May 2008 12:59:10 -0700
parents 4f22928c7a2c
children
line wrap: on
line source

from xpcom import components, verbose
import sys, os
import logging
import platform

_ensoStarted = False

ENSO_PATH = os.path.join(os.getenv("HOME"), "Documents/enso-svn")
LOGGING_FILE = os.path.join(os.getenv("HOME"), "enso_pyxpcom.log")

def getFuelApplication():
    from xpcom import components
    fuel_cls = components.classes["@mozilla.org/fuel/application;1"]
    fuel_abs = fuel_cls.createInstance()
    fuel_if = components.interfaces.fuelIApplication
    return fuel_abs.queryInterface(fuel_if)

def getCommandDispatcher():
    ci = components.interfaces
    cc = components.classes

    Application = getFuelApplication()
    document = Application.activeWindow.activeTab.document

    mediator = cc["@mozilla.org/appshell/window-mediator;1"].getService(
        ci.nsIWindowMediator
        )
    window = mediator.getMostRecentWindow("navigator:browser")
    return window.document.commandDispatcher

def firefoxSelectionHook():
    import AppKit

    app = AppKit.NSWorkspace.sharedWorkspace().activeApplication()
    if app["NSApplicationProcessIdentifier"] == os.getpid():
        return getFirefoxSelection()
    else:
        from enso.platform.osx import selection

        return selection._old_get()

def getFirefoxSelection():
    text = ""
    dispatcher = getCommandDispatcher()

    if dispatcher.focusedElement:
        start = dispatcher.focusedElement.selectionStart
        end = dispatcher.focusedElement.selectionEnd
        if start != end:
            text = dispatcher.focusedElement.value[start:end]
        else:
            text = dispatcher.focusedElement.value
    elif dispatcher.focusedWindow:
        sel = dispatcher.focusedWindow.getSelection()
        if sel.rangeCount >= 1:
            text = sel.toString()

    return {"text" : text,
            "dom.element" : dispatcher.focusedElement,
            "dom.window" : dispatcher.focusedWindow}

def installFirefoxSelectionHook():
    from enso.platform.osx import selection

    selection._old_get = selection.get
    selection.get = firefoxSelectionHook

def getAbout():
    global _ensoStarted

    if not _ensoStarted:
        logging.info("Importing Enso.")
        sys.path.append(ENSO_PATH)

        import enso

        logging.info("Installing Firefox selection hook.")
        installFirefoxSelectionHook()
        logging.info("Launching Enso.")
        _ensoStarted = True
        enso.run()

    return "Enso is running."

class ShutdownObserver:
    _com_interfaces_ = components.interfaces.nsIObserver

    def observe(self, subject, topic, data):
        print "quit-application received; calling sys.exitfunc()."
        sys.exitfunc()

class AboutPython:
    _com_interfaces_ = components.interfaces.nsIAboutModule
    _reg_contractid_ = '@mozilla.org/network/protocol/about;1?what=enso'
    _reg_clsid_ = '{6d5d462e-6de7-4bca-bbc6-c488d481351c}'
    _reg_desc_ = "about:enso handler"

    def __init__(self):
        logging.basicConfig(level=logging.INFO,
                            filename=LOGGING_FILE,
                            filemode="w")
        logging.info("Setting shutdown observer.")
        observerService = components.classes["@mozilla.org/observer-service;1"].getService(components.interfaces.nsIObserverService)
        observerService.addObserver(ShutdownObserver(), "quit-application", False)

    def newChannel(self, aURI):
        ioService = components.classes["@mozilla.org/network/io-service;1"] \
            .getService();

        istream = components.classes["@mozilla.org/io/string-input-stream;1"] \
            .createInstance()

        about = getAbout()
        istream.setData(about, len(about))

        channel = components.classes["@mozilla.org/network/input-stream-channel;1"] \
            .createInstance(components.interfaces.nsIInputStreamChannel)

        channel.setURI(aURI)
        #channel.contentType = "text/html"
        channel.contentStream = istream
        return channel

    def getURIFlags(self, aURI):
        return 0;