Commit eafac177 authored by Christian Hergert's avatar Christian Hergert

html-preview: port to libide-webkit and libide-editor

parent 78ea5a00
<?xml version="1.0"?> <?xml version="1.0"?>
<interface> <interface>
<menu id="ide-editor-view-document-menu"> <menu id="ide-editor-page-document-menu">
<section id="editor-document-section"> <section id="editor-document-section">
<item> <item>
<attribute name="after">editor-document-open-in-new-frame</attribute> <attribute name="after">editor-document-open-in-new-frame</attribute>
<attribute name="label" translatable="yes">Open Preview</attribute> <attribute name="label" translatable="yes">Open Preview</attribute>
<attribute name="action">editor-view.preview-as-html</attribute> <attribute name="action">editor-page.preview-as-html</attribute>
</item> </item>
</section> </section>
</menu> </menu>
......
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<gresources> <gresources>
<gresource prefix="/org/gnome/builder/plugins/html_preview"> <gresource prefix="/plugins/html_preview">
<file>js/markdown-view.js</file> <file>js/markdown-view.js</file>
<file>js/marked.js</file> <file>js/marked.js</file>
<file>css/markdown.css</file> <file>css/markdown.css</file>
......
[Plugin] [Plugin]
Module=html_preview
Loader=python3
Name=HTML, reStructuredText and Markdown Preview
Description=Live preview of HTML, reStructuredText and Markdown documents.
Authors=Christian Hergert <christian@hergert.me> Authors=Christian Hergert <christian@hergert.me>
Copyright=Copyright © 2015 Christian Hergert
Builtin=true Builtin=true
Depends=webkit Copyright=Copyright © 2015 Christian Hergert
Depends=webkit;
Description=Live preview of HTML, reStructuredText and Markdown documents.
Loader=python3
Module=html_preview
Name=HTML, reStructuredText and Markdown Preview
X-Editor-View-Languages=* X-Editor-View-Languages=*
X-Builder-ABI=@PACKAGE_ABI@
X-Has-Resources=true
...@@ -29,10 +29,6 @@ import sys ...@@ -29,10 +29,6 @@ import sys
import subprocess import subprocess
import threading import threading
gi.require_version('Gtk', '3.0')
gi.require_version('Ide', '1.0')
gi.require_version('WebKit2', '4.0')
from gi.repository import Dazzle from gi.repository import Dazzle
from gi.repository import GLib from gi.repository import GLib
from gi.repository import Gio from gi.repository import Gio
...@@ -124,13 +120,29 @@ class HtmlPreviewData(GObject.Object, Ide.ApplicationAddin): ...@@ -124,13 +120,29 @@ class HtmlPreviewData(GObject.Object, Ide.ApplicationAddin):
def get_data(self, name): def get_data(self, name):
# Hold onto the GBytes to avoid copying the buffer # Hold onto the GBytes to avoid copying the buffer
path = os.path.join('/org/gnome/builder/plugins/html_preview', name) path = os.path.join('/plugins/html_preview', name)
return Gio.resources_lookup_data(path, 0) return Gio.resources_lookup_data(path, 0)
class HtmlWorkbenchAddin(GObject.Object, Ide.WorkbenchAddin): class HtmlWorkbenchAddin(GObject.Object, Ide.WorkbenchAddin):
workbench = None
def do_load(self, workbench): def do_load(self, workbench):
self.workbench = workbench self.workbench = workbench
def do_unload(self, workbench):
self.workbench = None
def find_notif_by_id(self, id):
notifs = self.workbench.get_context().get_child_typed(Ide.Notifications)
return notifs.find_by_id(id)
def withdraw_notification(self, id):
notifs = self.workbench.get_context().get_child_typed(Ide.Notifications)
notif = notifs.find_by_id(id)
if notif is not None:
notif.withdraw()
def do_workspace_added(self, workspace):
group = Gio.SimpleActionGroup() group = Gio.SimpleActionGroup()
self.install_action = Gio.SimpleAction(name='install-docutils', enabled=True) self.install_action = Gio.SimpleAction(name='install-docutils', enabled=True)
...@@ -141,21 +153,26 @@ class HtmlWorkbenchAddin(GObject.Object, Ide.WorkbenchAddin): ...@@ -141,21 +153,26 @@ class HtmlWorkbenchAddin(GObject.Object, Ide.WorkbenchAddin):
self.install_action.connect('activate', lambda *_: self.install_sphinx()) self.install_action.connect('activate', lambda *_: self.install_sphinx())
group.insert(self.install_action) group.insert(self.install_action)
self.workbench.insert_action_group('html-preview', group) workspace.insert_action_group('html-preview', group)
def do_unload(self, workbench): def do_workspace_removed(self, workspace):
workbench.insert_action_group('html-preview', None) workspace.insert_action_group('html-preview', None)
self.workbench = None
def install_docutils(self): def install_docutils(self):
transfer = Ide.PkconTransfer(packages=['python3-docutils']) transfer = Ide.PkconTransfer(packages=['python3-docutils'])
manager = Gio.Application.get_default().get_transfer_manager() manager = Ide.TransferManager.get_default()
notif = transfer.create_notification()
notif.attach(self.workbench.get_context())
manager.execute_async(transfer, None, self.docutils_installed, None) manager.execute_async(transfer, None, self.docutils_installed, None)
def install_sphinx(self): def install_sphinx(self):
transfer = Ide.PkconTransfer(packages=['python3-sphinx']) transfer = Ide.PkconTransfer(packages=['python3-sphinx'])
manager = Gio.Application.get_default().get_transfer_manager() manager = Ide.TransferManager.get_default()
notif = transfer.create_notification()
notif.attach(self.workbench.get_context())
manager.execute_async(transfer, None, self.sphinx_installed, None) manager.execute_async(transfer, None, self.sphinx_installed, None)
...@@ -170,7 +187,7 @@ class HtmlWorkbenchAddin(GObject.Object, Ide.WorkbenchAddin): ...@@ -170,7 +187,7 @@ class HtmlWorkbenchAddin(GObject.Object, Ide.WorkbenchAddin):
return return
can_preview_rst = True can_preview_rst = True
self.workbench.pop_message('org.gnome.builder.docutils.install') self.withdraw_notification('org.gnome.builder.html-preview.docutils')
def sphinx_installed(self, object, result, data): def sphinx_installed(self, object, result, data):
global can_preview_sphinx global can_preview_sphinx
...@@ -183,19 +200,19 @@ class HtmlWorkbenchAddin(GObject.Object, Ide.WorkbenchAddin): ...@@ -183,19 +200,19 @@ class HtmlWorkbenchAddin(GObject.Object, Ide.WorkbenchAddin):
return return
can_preview_sphinx = True can_preview_sphinx = True
self.workbench.pop_message('org.gnome.builder.sphinx.install') self.withdraw_notification('org.gnome.builder.html-preview.docutils')
self.withdraw_notification('org.gnome.builder.html-preview.sphinx')
class HtmlPreviewAddin(GObject.Object, Ide.EditorViewAddin): class HtmlPreviewAddin(GObject.Object, Ide.EditorPageAddin):
def do_load(self, view): def do_load(self, view):
self.workbench = view.get_ancestor(Ide.Workbench) self.context = Ide.widget_get_context(view)
self.view = view self.view = view
self.can_preview = False self.can_preview = False
self.sphinx_basedir = None self.sphinx_basedir = None
self.sphinx_builddir = None self.sphinx_builddir = None
group = view.get_action_group('editor-view') group = view.get_action_group('editor-page')
self.action = Gio.SimpleAction(name='preview-as-html', enabled=True) self.action = Gio.SimpleAction(name='preview-as-html', enabled=True)
self.activate_handler = self.action.connect('activate', self.preview_activated) self.activate_handler = self.action.connect('activate', self.preview_activated)
...@@ -212,17 +229,17 @@ class HtmlPreviewAddin(GObject.Object, Ide.EditorViewAddin): ...@@ -212,17 +229,17 @@ class HtmlPreviewAddin(GObject.Object, Ide.EditorViewAddin):
controller.add_command_action('org.gnome.builder.html-preview.preview', controller.add_command_action('org.gnome.builder.html-preview.preview',
'<Control><Alt>p', '<Control><Alt>p',
Dazzle.ShortcutPhase.CAPTURE, Dazzle.ShortcutPhase.CAPTURE,
'editor-view.preview-as-html') 'editor-page.preview-as-html')
def do_unload(self, view): def do_unload(self, view):
self.action.disconnect(self.activate_handler) self.action.disconnect(self.activate_handler)
group = view.get_action_group('editor-view') group = view.get_action_group('editor-page')
group.remove_action('preview-as-html') group.remove_action('preview-as-html')
self.action = None self.action = None
self.view = None self.view = None
self.workbench = None self.context = None
def do_language_changed(self, language_id): def do_language_changed(self, language_id):
enabled = (language_id in ('html', 'markdown', 'rst')) enabled = (language_id in ('html', 'markdown', 'rst'))
...@@ -233,7 +250,7 @@ class HtmlPreviewAddin(GObject.Object, Ide.EditorViewAddin): ...@@ -233,7 +250,7 @@ class HtmlPreviewAddin(GObject.Object, Ide.EditorViewAddin):
if self.lang_id == 'rst': if self.lang_id == 'rst':
if not self.sphinx_basedir: if not self.sphinx_basedir:
document = self.view.get_buffer() document = self.view.get_buffer()
path = document.get_file().get_file().get_path() path = document.get_file().get_path()
self.sphinx_basedir = self.search_sphinx_base_dir(path) self.sphinx_basedir = self.search_sphinx_base_dir(path)
if self.sphinx_basedir: if self.sphinx_basedir:
...@@ -273,7 +290,7 @@ class HtmlPreviewAddin(GObject.Object, Ide.EditorViewAddin): ...@@ -273,7 +290,7 @@ class HtmlPreviewAddin(GObject.Object, Ide.EditorViewAddin):
return return
document = view.get_buffer() document = view.get_buffer()
web_view = HtmlPreviewView(document, web_view = HtmlPreviewPage(document,
self.sphinx_basedir, self.sphinx_basedir,
self.sphinx_builddir, self.sphinx_builddir,
visible=True) visible=True)
...@@ -295,9 +312,7 @@ class HtmlPreviewAddin(GObject.Object, Ide.EditorViewAddin): ...@@ -295,9 +312,7 @@ class HtmlPreviewAddin(GObject.Object, Ide.EditorViewAddin):
self.action.set_enabled(True) self.action.set_enabled(True)
def search_sphinx_base_dir(self, path): def search_sphinx_base_dir(self, path):
context = self.workbench.get_context() working_dir = self.context.ref_workdir()
vcs = context.get_vcs()
working_dir = vcs.get_working_directory().get_path()
try: try:
if os.path.commonpath([working_dir, path]) != working_dir: if os.path.commonpath([working_dir, path]) != working_dir:
...@@ -321,27 +336,26 @@ class HtmlPreviewAddin(GObject.Object, Ide.EditorViewAddin): ...@@ -321,27 +336,26 @@ class HtmlPreviewAddin(GObject.Object, Ide.EditorViewAddin):
folder = os.path.dirname(folder) folder = os.path.dirname(folder)
def show_missing_docutils_message(self, view): def show_missing_docutils_message(self, view):
message = Ide.WorkbenchMessage( notif = Ide.Notification(
id='org.gnome.builder.docutils.install', id='org.gnome.builder.html-preview.docutils',
title=_('Your computer is missing python3-docutils'), title=_('Your computer is missing python3-docutils'),
show_close_button=True, body=_('This package is necessary to provide previews of markup-based documents.'),
visible=True) icon_name='dialog-warning-symbolic',
urgent=True)
message.add_action(_('Install'), 'html-preview.install-docutils') notif.add_button(_('Install Package'), None, 'html-preview.install-docutils')
self.workbench.push_message(message) notif.attach(self.context)
def show_missing_sphinx_message(self, view): def show_missing_sphinx_message(self, view):
message = Ide.WorkbenchMessage( notif = Ide.Notification(
id='org.gnome.builder.sphinx.install', id='org.gnome.builder.html-preview.sphinx',
title=_('Your computer is missing python3-sphinx'), title=_('Your computer is missing python3-sphinx'),
show_close_button=True, body=_('This package is necessary to provide previews of markup-based documents.'),
visible=True) icon_name='dialog-warning-symbolic',
urgent=True)
message.add_action(_('Install'), 'html-preview.install-sphinx') notif.add_button(_('Install Package'), None, 'html-preview.install-sphinx')
self.workbench.push_message(message) notif.attach(self.context)
class HtmlPreviewPage(Ide.Page):
class HtmlPreviewView(Ide.LayoutView):
markdown = False markdown = False
rst = False rst = False
...@@ -352,13 +366,16 @@ class HtmlPreviewView(Ide.LayoutView): ...@@ -352,13 +366,16 @@ class HtmlPreviewView(Ide.LayoutView):
def __init__(self, document, sphinx_basedir, sphinx_builddir, *args, **kwargs): def __init__(self, document, sphinx_basedir, sphinx_builddir, *args, **kwargs):
global old_open global old_open
super().__init__(*args, **kwargs) print("Test");
Ide.Page.__init__(self, *args, **kwargs)
#super().__init__(self, *args, **kwargs)
self.sphinx_basedir = sphinx_basedir self.sphinx_basedir = sphinx_basedir
self.sphinx_builddir = sphinx_builddir self.sphinx_builddir = sphinx_builddir
self.document = document self.document = document
self.webview = WebKit2.WebView(visible=True, expand=True) self.webview = WebKit2.WebView.new(expand=True, visible=True)
self.add(self.webview) self.add(self.webview)
settings = self.webview.get_settings() settings = self.webview.get_settings()
...@@ -429,7 +446,7 @@ class HtmlPreviewView(Ide.LayoutView): ...@@ -429,7 +446,7 @@ class HtmlPreviewView(Ide.LayoutView):
name='sphinx-rst-thread').start() name='sphinx-rst-thread').start()
def purge_cache(self, basedir, builddir, document): def purge_cache(self, basedir, builddir, document):
path = document.get_file().get_file().get_path() path = document.get_file().get_path()
rel_path = os.path.relpath(path, start=basedir) rel_path = os.path.relpath(path, start=basedir)
rel_path_doctree = os.path.splitext(rel_path)[0] + '.doctree' rel_path_doctree = os.path.splitext(rel_path)[0] + '.doctree'
doctree_path = os.path.join(builddir, '.doctrees', rel_path_doctree) doctree_path = os.path.join(builddir, '.doctrees', rel_path_doctree)
...@@ -483,7 +500,7 @@ class HtmlPreviewView(Ide.LayoutView): ...@@ -483,7 +500,7 @@ class HtmlPreviewView(Ide.LayoutView):
state.need_build = True state.need_build = True
return return
gfile = self.document.get_file().get_file() gfile = self.document.get_file()
base_uri = gfile.get_uri() base_uri = gfile.get_uri()
begin, end = self.document.get_bounds() begin, end = self.document.get_bounds()
......
if get_option('with_html_preview') if get_option('plugin_html_preview')
html_preview_resources = gnome.compile_resources( html_preview_resources = gnome.compile_resources(
'html_preview', 'html_preview',
...@@ -13,7 +13,7 @@ install_data('html_preview.py', install_dir: plugindir) ...@@ -13,7 +13,7 @@ install_data('html_preview.py', install_dir: plugindir)
configure_file( configure_file(
input: 'html-preview.plugin', input: 'html-preview.plugin',
output: 'html-preview.plugin', output: 'html-preview.plugin',
copy: true, configuration: config_h,
install: true, install: true,
install_dir: plugindir, install_dir: plugindir,
) )
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment