1
"""
2
Patches bokeh resources to make it easy to add external JS and CSS
3
resources via the panel.config object.
4
"""
5 7
from __future__ import absolute_import, division, unicode_literals
6

7 7
import glob
8 7
import json
9 7
import os
10

11 7
from collections import OrderedDict
12 7
from pathlib import Path
13 7
from urllib.parse import urljoin
14

15 7
from bokeh.resources import Resources
16 7
from bokeh.settings import settings
17 7
from jinja2 import Environment, Markup, FileSystemLoader
18

19 7
with open(Path(__file__).parent.parent / 'package.json') as f:
20 7
    package_json = json.load(f)
21 7
    js_version = package_json['version'].split('+')[0]
22

23 7
CDN_DIST = f"https://unpkg.com/@holoviz/panel@{js_version}/dist/"
24 7
LOCAL_DIST = "static/extensions/panel/"
25 7
DIST_DIR = Path(__file__).parent.parent / 'dist'
26

27

28 7
def get_env():
29
    ''' Get the correct Jinja2 Environment, also for frozen scripts.
30
    '''
31 7
    local_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '_templates'))
32 7
    return Environment(loader=FileSystemLoader(local_path))
33

34 7
def css_raw(self):
35 7
    from ..config import config
36 7
    raw = super(Resources, self).css_raw
37 7
    for cssf in config.css_files:
38 0
        if not os.path.isfile(cssf):
39 0
            continue
40 0
        with open(cssf, encoding='utf-8') as f:
41 0
            css_txt = f.read()
42 0
            if css_txt not in raw:
43 0
                raw.append(css_txt)
44 7
    resources = settings.resources(default='server')
45 7
    for cssf in glob.glob(str(DIST_DIR / 'css' / '*.css')):
46 7
        if resources != 'inline':
47 7
            break
48 0
        with open(cssf, encoding='utf-8') as f:
49 0
            css_txt = f.read()
50 0
        if css_txt not in raw:
51 0
            raw.append(css_txt)
52 7
    return raw + config.raw_css
53

54 7
def js_files(self):
55 7
    from ..config import config
56 7
    files = super(Resources, self).js_files
57 7
    js_files = files + list(config.js_files.values())
58

59
    # Load requirejs last to avoid interfering with other libraries
60 7
    require_index = [i for i, jsf in enumerate(js_files) if 'require' in jsf]
61 7
    resources = settings.resources(default='server')
62 7
    if resources == 'server':
63 7
        dist_dir = urljoin(self.root_url, LOCAL_DIST)
64
    else:
65 0
        dist_dir = CDN_DIST
66 7
    if require_index:
67 0
        requirejs = js_files.pop(require_index[0])
68 0
        if any('ace' in jsf for jsf in js_files):
69 0
            js_files.append(dist_dir + 'pre_require.js')
70 0
        js_files.append(requirejs)
71 0
        if any('ace' in jsf for jsf in js_files):
72 0
            js_files.append(dist_dir + 'post_require.js')
73 7
    return js_files
74

75 7
def css_files(self):
76 7
    from ..config import config
77

78 7
    files = super(Resources, self).css_files
79 7
    for cssf in config.css_files:
80 0
        if os.path.isfile(cssf) or cssf in files:
81 0
            continue
82 0
        files.append(cssf)
83 7
    resources = settings.resources(default='server')
84 7
    if resources == 'server':
85 7
        dist_dir = urljoin(self.root_url, LOCAL_DIST)
86
    else:
87 0
        dist_dir = CDN_DIST
88 7
    for cssf in glob.glob(str(DIST_DIR / 'css' / '*.css')):
89 7
        if resources == 'inline':
90 0
            break
91 7
        files.append(dist_dir + f'css/{os.path.basename(cssf)}')
92 7
    return files
93

94 7
def conffilter(value):
95 0
    return json.dumps(OrderedDict(value)).replace('"', '\'')
96

97 7
_env = get_env()
98 7
_env.filters['json'] = lambda obj: Markup(json.dumps(obj))
99 7
_env.filters['conffilter'] = conffilter
100

101 7
Resources.css_raw = property(css_raw)
102 7
Resources.js_files = property(js_files)
103 7
Resources.css_files = property(css_files)

Read our documentation on viewing source code .

Loading