Skip to content

Commit

Permalink
Expose stylesheet model API publicly (#12688)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattpap committed Dec 19, 2022
1 parent a6237e5 commit cddffd5
Show file tree
Hide file tree
Showing 16 changed files with 315 additions and 75 deletions.
28 changes: 19 additions & 9 deletions bokehjs/src/lib/core/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,10 +418,19 @@ export enum MouseButton {

import {CSSOurStyles} from "./css"

export class StyleSheet {
readonly el: HTMLStyleElement
export abstract class StyleSheet {
protected readonly el: HTMLStyleElement | HTMLLinkElement

install(el: HTMLElement | ShadowRoot): void {
el.append(this.el)
}
}

export class InlineStyleSheet extends StyleSheet {
protected override readonly el: HTMLStyleElement

constructor(css?: string) {
super()
this.el = style({type: "text/css"}, css)
}

Expand Down Expand Up @@ -465,18 +474,19 @@ export class StyleSheet {
}
}

export class GlobalStyleSheet extends StyleSheet {
initialize(): void {
export class GlobalInlineStyleSheet extends InlineStyleSheet {
override install(): void {
if (!this.el.isConnected) {
document.head.appendChild(this.el)
}
}
}

export class ImportedStyleSheet {
readonly el: HTMLLinkElement
export class ImportedStyleSheet extends StyleSheet {
protected override readonly el: HTMLLinkElement

constructor(url: string) {
super()
this.el = link({rel: "stylesheet", href: url})
}

Expand All @@ -489,15 +499,15 @@ export class ImportedStyleSheet {
}
}

export class GlobalImportedStyleSheet extends StyleSheet {
initialize(): void {
export class GlobalImportedStyleSheet extends ImportedStyleSheet {
override install(): void {
if (!this.el.isConnected) {
document.head.appendChild(this.el)
}
}
}

export type StyleSheetLike = StyleSheet | ImportedStyleSheet | string
export type StyleSheetLike = StyleSheet | string

export async function dom_ready(): Promise<void> {
if (document.readyState == "loading") {
Expand Down
6 changes: 3 additions & 3 deletions bokehjs/src/lib/core/dom_view.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {View} from "./view"
import {createElement, remove, empty, StyleSheet, StyleSheetLike, ClassList} from "./dom"
import {createElement, remove, empty, InlineStyleSheet, StyleSheetLike, ClassList} from "./dom"
import {isString} from "./util/types"
import base_css from "styles/base.css"

Expand Down Expand Up @@ -104,8 +104,8 @@ export abstract class DOMComponentView extends DOMElementView {
} else {
*/
for (const style of stylesheets) {
const stylesheet = isString(style) ? new StyleSheet(style) : style
this.shadow_el.appendChild(stylesheet.el)
const stylesheet = isString(style) ? new InlineStyleSheet(style) : style
stylesheet.install(this.shadow_el)
}
}

Expand Down
6 changes: 3 additions & 3 deletions bokehjs/src/lib/core/util/menus.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {div, empty, remove, StyleSheet, StyleSheetLike, ClassList} from "../dom"
import {div, empty, remove, InlineStyleSheet, StyleSheetLike, ClassList} from "../dom"
import {Orientation} from "../enums"
import {reversed} from "./array"
import {isString} from "./types"
Expand Down Expand Up @@ -164,8 +164,8 @@ export class ContextMenu { //extends DOMComponentView {
this.empty()

for (const style of this.styles()) {
const stylesheet = isString(style) ? new StyleSheet(style) : style
this.shadow_el.appendChild(stylesheet.el)
const stylesheet = isString(style) ? new InlineStyleSheet(style) : style
stylesheet.install(this.shadow_el)
}

this.class_list.add(menus[this.orientation])
Expand Down
4 changes: 2 additions & 2 deletions bokehjs/src/lib/models/canvas/canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {Context2d, CanvasLayer} from "core/util/canvas"
import {UIElement, UIElementView} from "../ui/ui_element"
import {type PlotView} from "../plots/plot"
import type {ReglWrapper} from "../glyphs/webgl/regl_wrap"
import {StyleSheet, StyleSheetLike} from "core/dom"
import {InlineStyleSheet, StyleSheetLike} from "core/dom"
import canvas_css from "styles/canvas.css"

export type FrameBox = [number, number, number, number]
Expand Down Expand Up @@ -80,7 +80,7 @@ export class CanvasView extends UIElementView {

ui_event_bus: UIEventBus

protected _size = new StyleSheet()
protected _size = new InlineStyleSheet()

override initialize(): void {
super.initialize()
Expand Down
1 change: 1 addition & 0 deletions bokehjs/src/lib/models/dom/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export {HTML} from "./html"
export {Index} from "./index_"
export {Placeholder} from "./placeholder"
export {Styles} from "./styles"
export {InlineStyleSheet, GlobalInlineStyleSheet, ImportedStyleSheet, GlobalImportedStyleSheet} from "./stylesheets"
export {Template} from "./template"
export {Text} from "./text"
export {ToggleGroup} from "./toggle_group"
Expand Down
120 changes: 120 additions & 0 deletions bokehjs/src/lib/models/dom/stylesheets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import {Model} from "../../model"
import * as dom from "core/dom"
import * as p from "core/properties"

export namespace StyleSheet {
export type Attrs = p.AttrsOf<Props>
export type Props = Model.Props
}

export interface StyleSheet extends StyleSheet.Attrs {}

export abstract class StyleSheet extends Model {
override properties: StyleSheet.Props

constructor(attrs?: Partial<StyleSheet.Attrs>) {
super(attrs)
}

abstract underlying(): dom.StyleSheet
}

export namespace InlineStyleSheet {
export type Attrs = p.AttrsOf<Props>
export type Props = StyleSheet.Props & {
css: p.Property<string>
}
}

export interface InlineStyleSheet extends InlineStyleSheet.Attrs {}

export class InlineStyleSheet extends StyleSheet {
override properties: InlineStyleSheet.Props

constructor(attrs?: Partial<InlineStyleSheet.Attrs>) {
super(attrs)
}

static {
this.define<InlineStyleSheet.Props>(({String}) => ({
css: [ String ],
}))
}

underlying(): dom.StyleSheet {
return new dom.InlineStyleSheet(this.css)
}
}

export namespace ImportedStyleSheet {
export type Attrs = p.AttrsOf<Props>
export type Props = StyleSheet.Props & {
url: p.Property<string>
}
}

export interface ImportedStyleSheet extends ImportedStyleSheet.Attrs {}

export class ImportedStyleSheet extends StyleSheet {
override properties: ImportedStyleSheet.Props

constructor(attrs?: Partial<ImportedStyleSheet.Attrs>) {
super(attrs)
}

static {
this.define<ImportedStyleSheet.Props>(({String}) => ({
url: [ String ],
}))
}

underlying(): dom.StyleSheet {
return new dom.ImportedStyleSheet(this.url)
}
}

export namespace GlobalInlineStyleSheet {
export type Attrs = p.AttrsOf<Props>
export type Props = InlineStyleSheet.Props
}

export interface GlobalInlineStyleSheet extends GlobalInlineStyleSheet.Attrs {}

export class GlobalInlineStyleSheet extends InlineStyleSheet {
override properties: GlobalInlineStyleSheet.Props

constructor(attrs?: Partial<GlobalInlineStyleSheet.Attrs>) {
super(attrs)
}

private _underlying: dom.StyleSheet | null = null

override underlying(): dom.StyleSheet {
if (this._underlying == null)
this._underlying = new dom.GlobalInlineStyleSheet(this.css)
return this._underlying
}
}

export namespace GlobalImportedStyleSheet {
export type Attrs = p.AttrsOf<Props>
export type Props = ImportedStyleSheet.Props
}

export interface GlobalImportedStyleSheet extends GlobalImportedStyleSheet.Attrs {}

export class GlobalImportedStyleSheet extends ImportedStyleSheet {
override properties: GlobalImportedStyleSheet.Props

constructor(attrs?: Partial<GlobalImportedStyleSheet.Attrs>) {
super(attrs)
}

private _underlying: dom.StyleSheet | null = null

override underlying(): dom.StyleSheet {
if (this._underlying == null)
this._underlying = new dom.GlobalInlineStyleSheet(this.url)
return this._underlying
}
}
4 changes: 2 additions & 2 deletions bokehjs/src/lib/models/plots/plot_canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {parse_css_font_size} from "core/util/text"
import {RangeInfo, RangeOptions, RangeManager} from "./range_manager"
import {StateInfo, StateManager} from "./state_manager"
import {settings} from "core/settings"
import {StyleSheet, StyleSheetLike, px} from "core/dom"
import {InlineStyleSheet, StyleSheetLike, px} from "core/dom"

import plots_css from "styles/plots.css"

Expand All @@ -54,7 +54,7 @@ export class PlotView extends LayoutDOMView implements Renderable {
return this.canvas_view
}

protected _computed_style = new StyleSheet()
protected _computed_style = new InlineStyleSheet()

override styles(): StyleSheetLike[] {
return [...super.styles(), plots_css, this._computed_style]
Expand Down
6 changes: 3 additions & 3 deletions bokehjs/src/lib/models/tiles/tile_renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {Plot} from "../plots/plot"
import {CartesianFrame} from "../canvas/cartesian_frame"
import {Range} from "../ranges/range"
import {Range1d} from "../ranges/range1d"
import {div, remove, StyleSheet} from "core/dom"
import {div, remove, InlineStyleSheet} from "core/dom"
import * as p from "core/properties"
import {Image, ImageLoader} from "core/util/image"
import {includes} from "core/util/array"
Expand Down Expand Up @@ -112,8 +112,8 @@ export class TileRendererView extends RendererView {
contents_el.innerHTML = attribution

const shadow_el = this.attribution_el.attachShadow({mode: "open"})
const stylesheet = new StyleSheet(attribution_css)
shadow_el.appendChild(stylesheet.el)
const stylesheet = new InlineStyleSheet(attribution_css)
stylesheet.install(shadow_el)
shadow_el.appendChild(contents_el)

this.attribution_el.title = contents_el.textContent!.replace(/\s*\n\s*/g, " ")
Expand Down
4 changes: 2 additions & 2 deletions bokehjs/src/lib/models/ui/icons/builtin_icon.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Icon, IconView} from "./icon"
import {Color} from "core/types"
import {StyleSheet, StyleSheetLike} from "core/dom"
import {InlineStyleSheet, StyleSheetLike} from "core/dom"
import {color2css} from "core/util/color"
import {isNumber} from "core/util/types"
import * as p from "core/properties"
Expand All @@ -10,7 +10,7 @@ import icons_css from "styles/icons.css"
export class BuiltinIconView extends IconView {
override model: BuiltinIcon

protected readonly _style = new StyleSheet()
protected readonly _style = new InlineStyleSheet()

override styles(): StyleSheetLike[] {
return [...super.styles(), icons_css, this._style]
Expand Down
4 changes: 2 additions & 2 deletions bokehjs/src/lib/models/ui/icons/svg_icon.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {Icon, IconView} from "./icon"
import {StyleSheet, StyleSheetLike} from "core/dom"
import {InlineStyleSheet, StyleSheetLike} from "core/dom"
import {isNumber} from "core/util/types"
import * as p from "core/properties"

export class SVGIconView extends IconView {
override model: SVGIcon

protected readonly _style = new StyleSheet()
protected readonly _style = new InlineStyleSheet()

override styles(): StyleSheetLike[] {
return [...super.styles(), this._style]
Expand Down
13 changes: 4 additions & 9 deletions bokehjs/src/lib/models/ui/icons/tabler_icon.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Icon, IconView} from "./icon"
import {span, StyleSheet, ImportedStyleSheet, GlobalStyleSheet, StyleSheetLike} from "core/dom"
import {span, InlineStyleSheet, ImportedStyleSheet, GlobalInlineStyleSheet, StyleSheetLike} from "core/dom"
import {isNumber} from "core/util/types"
import * as p from "core/properties"

Expand All @@ -8,7 +8,7 @@ export class TablerIconView extends IconView {

protected static readonly _url = "https://unpkg.com/@tabler/icons@latest/iconfont"

protected static readonly _fonts = new GlobalStyleSheet(`\
protected static readonly _fonts = new GlobalInlineStyleSheet(`\
/*!
* Tabler Icons 1.68.0 by tabler - https://tabler.io
* License - https://github.com/tabler/tabler-icons/blob/master/LICENSE
Expand All @@ -35,15 +35,10 @@ export class TablerIconView extends IconView {

protected readonly _tabler = new ImportedStyleSheet(`${TablerIconView._url}/tabler-icons.min.css`)

protected readonly _style = new StyleSheet()
protected readonly _style = new InlineStyleSheet()

override styles(): StyleSheetLike[] {
return [...super.styles(), this._tabler, this._style]
}

override initialize(): void {
super.initialize()
TablerIconView._fonts.initialize()
return [...super.styles(), TablerIconView._fonts, this._tabler, this._style]
}

override render(): void {
Expand Down

0 comments on commit cddffd5

Please sign in to comment.