| [16928] | 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | # |
|---|
| [17535] | 3 | # Copyright (C) 2017, 2019 MATOBA Akihiro <matobaa+trac-hacks@gmail.com> |
|---|
| [16928] | 4 | # All rights reserved. |
|---|
| 5 | # |
|---|
| 6 | # This software is licensed as described in the file COPYING, which |
|---|
| 7 | # you should have received as part of this distribution. |
|---|
| 8 | |
|---|
| 9 | from trac.core import Component, implements |
|---|
| 10 | from trac.prefs.api import IPreferencePanelProvider |
|---|
| 11 | from trac.util.translation import _ |
|---|
| 12 | from trac.web.chrome import ITemplateProvider, add_notice, add_stylesheet,\ |
|---|
| 13 | add_script |
|---|
| 14 | from trac.web.api import IRequestHandler, IRequestFilter, HTTPException |
|---|
| 15 | from pkg_resources import ResourceManager |
|---|
| [17535] | 16 | from trac import __version__ as VERSION |
|---|
| [16928] | 17 | |
|---|
| 18 | _path_css = '/contextchrome/userstyle.css' |
|---|
| 19 | _path_js = '/contextchrome/userscript.js' |
|---|
| 20 | |
|---|
| 21 | |
|---|
| 22 | class UserStyle(Component): |
|---|
| 23 | """ inject user's own script or style to all page. """ |
|---|
| 24 | implements(IPreferencePanelProvider, IRequestFilter, |
|---|
| 25 | IRequestHandler, ITemplateProvider) |
|---|
| 26 | |
|---|
| 27 | # IRequestFilter methods |
|---|
| 28 | |
|---|
| 29 | def pre_process_request(self, req, handler): |
|---|
| 30 | pass # do nothing |
|---|
| 31 | return handler |
|---|
| 32 | |
|---|
| 33 | def post_process_request(self, req, template, data, content_type): |
|---|
| [16944] | 34 | if template and (template.startswith('prefs') or \ |
|---|
| 35 | template.startswith('admin')): |
|---|
| [16928] | 36 | pass # do nothing, for troubleshoot yourself |
|---|
| 37 | return template, data, content_type |
|---|
| 38 | if _path_css in req.session: |
|---|
| 39 | add_stylesheet(req, _path_css) |
|---|
| 40 | if _path_js in req.session: |
|---|
| 41 | add_script(req, _path_js) |
|---|
| 42 | return template, data, content_type |
|---|
| 43 | |
|---|
| 44 | # IRequestHandler methods |
|---|
| 45 | |
|---|
| 46 | def match_request(self, req): |
|---|
| 47 | return _path_css == req.path_info \ |
|---|
| 48 | or _path_js == req.path_info |
|---|
| 49 | |
|---|
| 50 | def process_request(self, req): |
|---|
| 51 | if _path_css == req.path_info: |
|---|
| 52 | content = req.session[_path_css] |
|---|
| 53 | content_type = 'text/css' |
|---|
| 54 | elif _path_js == req.path_info: |
|---|
| 55 | content = req.session[_path_js] |
|---|
| 56 | content_type = 'application/javascript' |
|---|
| 57 | else: |
|---|
| 58 | raise HTTPException('File %s not found', req.path_info) |
|---|
| 59 | req.send_response(200) |
|---|
| 60 | req.send_header('Content-Type', content_type) |
|---|
| 61 | # req.send_header('Last-Modified', last_modified) |
|---|
| 62 | req.send_header('Content-Length', len(content)) |
|---|
| 63 | req.write(str(content)) |
|---|
| 64 | |
|---|
| 65 | # IPreferencePanelProvider methods |
|---|
| 66 | |
|---|
| 67 | def get_preference_panels(self, req): |
|---|
| 68 | yield 'userstyle', _("User Style") |
|---|
| 69 | |
|---|
| 70 | def render_preference_panel(self, req, panel): |
|---|
| 71 | if req.method == 'POST': |
|---|
| 72 | if 'userstyle' in req.args: |
|---|
| 73 | if _path_css in req.session: |
|---|
| 74 | req.session.pop(_path_css) |
|---|
| 75 | userstyle = req.args.get('userstyle') |
|---|
| 76 | if userstyle: |
|---|
| 77 | req.session[_path_css] = userstyle |
|---|
| 78 | add_notice(req, _("Your preferences have been saved.")) |
|---|
| 79 | if 'userscript' in req.args: |
|---|
| 80 | if _path_js in req.session: |
|---|
| 81 | req.session.pop(_path_js) |
|---|
| 82 | userscript = req.args.get('userscript') |
|---|
| 83 | if userscript: |
|---|
| 84 | req.session[_path_js] = userscript |
|---|
| 85 | add_notice(req, _("Your preferences have been saved.")) |
|---|
| 86 | req.redirect(req.href.prefs(panel or None)) |
|---|
| 87 | |
|---|
| 88 | userstyle = req.session[_path_css] if _path_css in req.session else '' |
|---|
| 89 | userscript = req.session[_path_js] if _path_js in req.session else '' |
|---|
| 90 | data = {'userstyle': userstyle, |
|---|
| 91 | 'userscript': userscript} |
|---|
| [17535] | 92 | if VERSION < '1.3.2': |
|---|
| 93 | return 'genshi_prefs_userstyle.html', data |
|---|
| 94 | else: |
|---|
| 95 | return 'prefs_userstyle.html', data |
|---|
| [16928] | 96 | |
|---|
| 97 | # ITemplateProvider methods |
|---|
| 98 | |
|---|
| 99 | def get_htdocs_dirs(self): |
|---|
| 100 | return [] |
|---|
| 101 | |
|---|
| 102 | def get_templates_dirs(self): |
|---|
| 103 | return [ResourceManager().resource_filename('contextchrome', |
|---|
| 104 | 'templates')] |
|---|