Skip to content

Commit

Permalink
Serve codehilite CSS for ui.markdown more efficiently (#3792)
Browse files Browse the repository at this point in the history
* provide codehilite CSS via separate endpoint to enable caching

* fix some pytests
  • Loading branch information
falkoschindler authored Sep 27, 2024
1 parent d99d84e commit e47ec7a
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 16 deletions.
2 changes: 1 addition & 1 deletion nicegui/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ def shorten(content: Any, length: int = 20) -> str:
additions.append(f'text={shorten(self._text)}')
if hasattr(self, 'content') and self.content: # pylint: disable=no-member
additions.append(f'content={shorten(self.content)}') # pylint: disable=no-member
IGNORED_PROPS = {'loopback', 'color', 'view', 'innerHTML', 'codehilite_css'}
IGNORED_PROPS = {'loopback', 'color', 'view', 'innerHTML', 'codehilite_css_url'}
additions += [
f'{key}={shorten(value)}'
for key, value in self._props.items()
Expand Down
15 changes: 5 additions & 10 deletions nicegui/elements/markdown.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { loadResource } from "../../static/utils/resources.js";

export default {
template: `<div></div>`,
async mounted() {
this.ensure_codehilite_css();
await this.$nextTick(); // NOTE: wait for window.path_prefix to be set
await loadResource(window.path_prefix + this.codehilite_css_url);
if (this.use_mermaid) {
this.mermaid = (await import("mermaid")).default;
this.renderMermaid();
Expand All @@ -21,17 +24,9 @@ export default {
await this.mermaid.run({ nodes: [pre.children[0]] });
});
},
ensure_codehilite_css() {
if (!document.querySelector(`style[data-codehilite-css]`)) {
const style = document.createElement("style");
style.setAttribute("data-codehilite-css", "");
style.innerHTML = this.codehilite_css;
document.head.appendChild(style);
}
},
},
props: {
codehilite_css: String,
codehilite_css_url: String,
use_mermaid: {
required: false,
default: false,
Expand Down
17 changes: 13 additions & 4 deletions nicegui/elements/markdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@
from typing import List

import markdown2
from fastapi.responses import PlainTextResponse
from pygments.formatters import HtmlFormatter # pylint: disable=no-name-in-module

from .. import core
from ..version import __version__
from .mermaid import Mermaid
from .mixins.content_element import ContentElement

CODEHILITE_CSS_URL = f'/_nicegui/{__version__}/codehilite.css'


class Markdown(ContentElement, component='markdown.js'):

Expand All @@ -25,14 +30,18 @@ def __init__(self,
self.extras = extras[:]
super().__init__(content=content)
self._classes.append('nicegui-markdown')
self._props['codehilite_css'] = (
HtmlFormatter(nobackground=True).get_style_defs('.codehilite') +
HtmlFormatter(nobackground=True, style='github-dark').get_style_defs('.body--dark .codehilite')
)
if 'mermaid' in extras:
self._props['use_mermaid'] = True
self.libraries.append(Mermaid.exposed_libraries[0])

self._props['codehilite_css_url'] = CODEHILITE_CSS_URL
if not any(r for r in core.app.routes if getattr(r, 'path', None) == CODEHILITE_CSS_URL):
core.app.get(CODEHILITE_CSS_URL)(lambda: PlainTextResponse(
HtmlFormatter(nobackground=True).get_style_defs('.codehilite') +
HtmlFormatter(nobackground=True, style='github-dark').get_style_defs('.body--dark .codehilite'),
media_type='text/css',
))

def _handle_content_change(self, content: str) -> None:
html = prepare_content(content, extras=' '.join(self.extras))
if self._props.get('innerHTML') != html:
Expand Down
8 changes: 7 additions & 1 deletion tests/test_endpoint_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pytest
import requests

from nicegui import __version__
from nicegui import __version__, ui
from nicegui.testing import Screen


Expand All @@ -29,8 +29,11 @@ def test_endpoint_documentation_page_only(screen: Screen):

def test_endpoint_documentation_internal_only(screen: Screen):
screen.ui_run_kwargs['endpoint_documentation'] = 'internal'
ui.markdown('Hey!')

screen.open('/')
assert get_openapi_paths() == {
f'/_nicegui/{__version__}/codehilite.css',
f'/_nicegui/{__version__}/libraries/{{key}}',
f'/_nicegui/{__version__}/components/{{key}}',
f'/_nicegui/{__version__}/resources/{{key}}/{{path}}',
Expand All @@ -39,9 +42,12 @@ def test_endpoint_documentation_internal_only(screen: Screen):

def test_endpoint_documentation_all(screen: Screen):
screen.ui_run_kwargs['endpoint_documentation'] = 'all'
ui.markdown('Hey!')

screen.open('/')
assert get_openapi_paths() == {
'/',
f'/_nicegui/{__version__}/codehilite.css',
f'/_nicegui/{__version__}/libraries/{{key}}',
f'/_nicegui/{__version__}/components/{{key}}',
f'/_nicegui/{__version__}/resources/{{key}}/{{path}}',
Expand Down

0 comments on commit e47ec7a

Please sign in to comment.