Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to Sprotty 1.3.0 #191

Merged
merged 2 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion applications/klighd-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"pino-pretty": "^4.7.1",
"reflect-metadata": "^0.2.1",
"setimmediate": "^1.0.5",
"sprotty-protocol": "^1.1.0",
"sprotty-protocol": "^1.3.0",
"stream-browserify": "^3.0.0",
"vscode-languageserver-protocol": "^3.17.5",
"vscode-ws-jsonrpc": "^0.2.0",
Expand Down
4 changes: 2 additions & 2 deletions applications/klighd-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@
"inversify": "^6.0.2",
"nanoid": "^3.1.23",
"reflect-metadata": "^0.2.1",
"sprotty": "^1.1.0",
"sprotty-protocol": "^1.1.0",
"sprotty": "^1.3.0",
"sprotty-protocol": "^1.3.0",
"sprotty-vscode": "^1.0.0",
"sprotty-vscode-protocol": "^1.0.0",
"sprotty-vscode-webview": "^1.0.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/klighd-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
"file-saver": "^2.0.5",
"inversify": "^6.0.2",
"snabbdom": "^3.5.1",
"sprotty": "^1.1.0",
"sprotty-protocol": "^1.1.0"
"sprotty": "^1.3.0",
"sprotty-protocol": "^1.3.0"
},
"devDependencies": {
"@types/chai": "^4.3.11",
Expand Down
26 changes: 21 additions & 5 deletions packages/klighd-core/src/actions/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* http://rtsys.informatik.uni-kiel.de/kieler
*
* Copyright 2019-2022 by
* Copyright 2019-2024 by
* + Kiel University
* + Department of Computer Science
* + Real-Time and Embedded Systems Group
Expand All @@ -16,8 +16,17 @@
*/
// We follow Sprotty's way of redeclaring the interface and its create function, so disable this lint check for this file.
/* eslint-disable no-redeclare */
import { ExportSvgAction, RequestExportSvgAction, SGraphImpl } from 'sprotty'
import { Action, FitToScreenAction, generateRequestId, RequestAction, ResponseAction } from 'sprotty-protocol'
import { SGraphImpl } from 'sprotty'
import {
Action,
ExportSvgAction,
ExportSvgOptions,
FitToScreenAction,
generateRequestId,
RequestAction,
RequestExportSvgAction,
ResponseAction,
} from 'sprotty-protocol'
import { SKGraphModelRenderer } from '../skgraph-model-renderer'
import { KImage } from '../skgraph-models'

Expand Down Expand Up @@ -181,10 +190,11 @@ export namespace SendModelContextAction {
export type KlighdRequestExportSvgAction = RequestExportSvgAction

export namespace KlighdRequestExportSvgAction {
export function create(): RequestAction<KlighdExportSvgAction> {
export function create(options?: ExportSvgOptions): KlighdRequestExportSvgAction {
return {
kind: RequestExportSvgAction.KIND,
requestId: generateRequestId(),
options,
}
}
}
Expand All @@ -198,12 +208,18 @@ export interface KlighdExportSvgAction extends ExportSvgAction {
export namespace KlighdExportSvgAction {
export const KIND = 'exportSvg'

export function create(svg: string, requestId: string, uri: string): KlighdExportSvgAction {
export function create(
svg: string,
requestId: string,
uri: string,
options?: ExportSvgOptions
): KlighdExportSvgAction {
return {
kind: KIND,
svg,
responseId: requestId,
uri,
options,
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* http://rtsys.informatik.uni-kiel.de/kieler
*
* Copyright 2021-2023 by
* Copyright 2021-2024 by
* + Kiel University
* + Department of Computer Science
* + Real-Time and Embedded Systems Group
Expand All @@ -23,13 +23,10 @@ import { html } from 'sprotty' // eslint-disable-line @typescript-eslint/no-unus
/**
* Add the feather icon with the given icon ID to a snabbdom VNode as used in sprotty.
*
* @param paramProps properties containing the ID of the feather icon.
* @param props properties containing the ID of the feather icon.
* @returns The SVG VNode resulting from this feather icon ID.
*/
export function FeatherIcon(paramProps: { iconId: FeatherIconNames }): VNode {
// Something goes wrong with snabbdom functional components as that the props are nested in an
// addional props property, which is removed here.
const props = (paramProps as any).props as { iconId: FeatherIconNames }
export function FeatherIcon(props: { iconId: FeatherIconNames }): VNode {
// Imitates what feather would usually do, all attributes are put in the styles (if possible) and
// the classes are written in as well. Missing are the xmlns and viewBox, but they do not seem to
// be necessary anyways.
Expand Down
84 changes: 40 additions & 44 deletions packages/klighd-core/src/klighd-svg-exporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* http://rtsys.informatik.uni-kiel.de/kieler
*
* Copyright 2021-2023 by
* Copyright 2021-2024 by
* + Kiel University
* + Department of Computer Science
* + Real-Time and Embedded Systems Group
Expand All @@ -17,59 +17,55 @@

import { injectable } from 'inversify'
import { SModelRootImpl, SvgExporter } from 'sprotty'
import { RequestAction } from 'sprotty-protocol'
import { KlighdExportSvgAction } from './actions/actions'
/* global document, Element, HTMLIFrameElement, SVGSVGElement, XMLSerializer */
import { KlighdExportSvgAction, KlighdRequestExportSvgAction } from './actions/actions'
/* global document, Document, Element */

@injectable()
export class KlighdSvgExporter extends SvgExporter {
export(root: SModelRootImpl, request?: RequestAction<KlighdExportSvgAction>): void {
export(root: SModelRootImpl, request?: KlighdRequestExportSvgAction): void {
// Same as Sprotty's SvgExporter.export, but with KlighdExportSvgAction instead of
// ExportSvgAction to have a better default export name based on the root ID (its model URI).
if (typeof document !== 'undefined') {
const div = document.getElementById(this.options.hiddenDiv)
if (div !== null && div.firstElementChild && div.firstElementChild.tagName === 'svg') {
const svgElement = div.firstElementChild as SVGSVGElement
const svg = this.createSvg(svgElement, root)
this.actionDispatcher.dispatch(
KlighdExportSvgAction.create(svg, request ? request.requestId : '', root.id)
)
const hiddenDiv = document.getElementById(this.options.hiddenDiv)
if (hiddenDiv === null) {
this.log.warn(this, `Element with id ${this.options.hiddenDiv} not found. Nothing to export.`)
return
}

const svgElement = hiddenDiv.querySelector('svg')
if (svgElement === null) {
this.log.warn(this, `No svg element found in ${this.options.hiddenDiv} div. Nothing to export.`)
return
}
const svg = this.createSvg(svgElement, root, request?.options ?? {}, request)
this.actionDispatcher.dispatch(
KlighdExportSvgAction.create(svg, request ? request.requestId : '', root.id, request?.options)
)
}
}

protected createSvg(svgElementOrig: SVGSVGElement, root: SModelRootImpl): string {
const serializer = new XMLSerializer()
const svgCopy = serializer.serializeToString(svgElementOrig)
const iframe: HTMLIFrameElement = document.createElement('iframe')
document.body.appendChild(iframe)
if (!iframe.contentWindow) throw new Error('IFrame has no contentWindow')
const docCopy = iframe.contentWindow.document
docCopy.open()
docCopy.write(svgCopy)
docCopy.close()
const svgElementNew = docCopy.getElementById(svgElementOrig.id)!
this.copyStyles(svgElementOrig, svgElementNew, [])
svgElementNew.setAttribute('version', '1.1')
// Somehow this is always 1.
svgElementNew.setAttribute('opacity', '1')
const bounds = this.getBounds(root)
svgElementNew.setAttribute('viewBox', `${bounds.x} ${bounds.y} ${bounds.width} ${bounds.height}`)
const svgCode = serializer.serializeToString(svgElementNew)
document.body.removeChild(iframe)
return svgCode
protected copyStyles(_source: Element, _target: Element, _skippedProperties: string[]): void {
// Just don't copy the styles. This would overwrite any styles set by the SVG renderer and we do not need any other styles that may get copied here.
// So overwrite Sprotty's copyStyles method with an empty method.
}

protected copyStyles(source: Element, target: Element, skipedProperties: string[]): void {
source.getAttributeNames().forEach((key) => {
if (!skipedProperties.includes(key)) {
const value = source.getAttribute(key)
if (value) target.setAttribute(key, value)
}
})
// IE doesn't retrun anything on source.children
for (let i = 0; i < source.childNodes.length; ++i) {
const sourceChild = source.childNodes[i]
const targetChild = target.childNodes[i]
if (sourceChild instanceof Element) this.copyStyles(sourceChild, targetChild as Element, [])
protected getBounds(root: SModelRootImpl, document: Document) {
const svgElement = document.querySelector('svg')
if (svgElement) {
// Get the actual bounding box of the SVG element, including the stroke width.
// should use { stroke: true } argument here, but it's not supported in chromium.
const box = svgElement.getBBox()
// Instead, remove the x/y offset and assume that the diagram is at 0/0 and that the offset on the other side is the same.
const xOffset = box.x
const yOffset = box.y
box.x = 0
box.y = 0
box.width += xOffset * 2
box.height += yOffset * 2

return box
}

return super.getBounds(root, document)
}
}
14 changes: 1 addition & 13 deletions packages/klighd-core/src/options/components/option-inputs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* http://rtsys.informatik.uni-kiel.de/kieler
*
* Copyright 2021-2022 by
* Copyright 2021-2024 by
* + Kiel University
* + Department of Computer Science
* + Real-Time and Embedded Systems Group
Expand Down Expand Up @@ -34,8 +34,6 @@ type CheckOptionProps = BaseProps<boolean>

/** Render a labeled checkbox input. */
export function CheckOption(props: CheckOptionProps): VNode {
// The sprotty jsx function always puts an additional 'props' key around the element, requiring this hack.
props = (props as any as { props: CheckOptionProps }).props
return (
<label htmlFor={props.id} title={props.description ?? props.name}>
<input
Expand All @@ -58,8 +56,6 @@ interface ChoiceOptionProps extends BaseProps<string> {

/** Render a labeled group of radio inputs. */
export function ChoiceOption(props: ChoiceOptionProps): VNode {
// The sprotty jsx function always puts an additional 'props' key around the element, requiring this hack.
props = (props as any as { props: ChoiceOptionProps }).props
return (
<div class-options__input-container="true">
<legend>{props.name}</legend>
Expand Down Expand Up @@ -94,8 +90,6 @@ interface RangeOptionProps extends BaseProps<number> {

/** Render a labeled range slider as input. */
export function RangeOption(props: RangeOptionProps): VNode {
// The sprotty jsx function always puts an additional 'props' key around the element, requiring this hack.
props = (props as any as { props: RangeOptionProps }).props
return (
<div class-options__column="true">
<label htmlFor={props.id} title={props.description ?? props.name}>
Expand All @@ -121,8 +115,6 @@ type TextOptionProps = BaseProps<string>

/** Renders a labeled text input. */
export function TextOption(props: TextOptionProps): VNode {
// The sprotty jsx function always puts an additional 'props' key around the element, requiring this hack.
props = (props as any as { props: TextOptionProps }).props
return (
<div class-options__column="true">
<label htmlFor={props.id} title={props.description ?? props.name}>
Expand All @@ -143,8 +135,6 @@ export function TextOption(props: TextOptionProps): VNode {

/** Renders a named separator. */
export function SeparatorOption(props: { name: string; key?: string }): VNode {
// The sprotty jsx function always puts an additional 'props' key around the element, requiring this hack.
props = (props as any as { props: { name: string; key?: string } }).props
return <span class-options__separator="true">{props.name}</span>
}

Expand All @@ -155,8 +145,6 @@ interface CategoryOptionProps extends BaseProps<boolean> {

/** Renders a labeled options group. */
export function CategoryOption(props: CategoryOptionProps, children: VNode[]): VNode {
// The sprotty jsx function always puts an additional 'props' key around the element, requiring this hack.
props = (props as any as { props: CategoryOptionProps }).props
function handleToggle(e: any) {
// The toggle event is also fired if the details are rendered default open.
// To prevent an infinite toggle loop, change is only called if the state has really changed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* http://rtsys.informatik.uni-kiel.de/kieler
*
* Copyright 2021 by
* Copyright 2021-2024 by
* + Kiel University
* + Department of Computer Science
* + Real-Time and Embedded Systems Group
Expand All @@ -26,8 +26,6 @@ interface SynthesisPickerProps {
}

export function SynthesisPicker(props: SynthesisPickerProps): VNode {
// The sprotty jsx function always puts an additional 'props' key around the element, requiring this hack.
props = (props as any as { props: SynthesisPickerProps }).props
return (
<div class-options__column="true">
<label htmlFor="synthesisSelect">Current synthesis:</label>
Expand Down
4 changes: 1 addition & 3 deletions packages/klighd-core/src/sidebar/sidebar-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* http://rtsys.informatik.uni-kiel.de/kieler
*
* Copyright 2021-2023 by
* Copyright 2021-2024 by
* + Kiel University
* + Department of Computer Science
* + Real-Time and Embedded Systems Group
Expand Down Expand Up @@ -223,8 +223,6 @@ interface QuickActionsBarProps {
* This method creates the quick actions bar as a resuable component.
*/
export function QuickActionsBar(props: QuickActionsBarProps): VNode {
// The Sprotty jsx function always puts an additional 'props' key around the element, requiring this hack.
props = (props as any as { props: QuickActionsBarProps }).props
return (
<div class-options__section="true">
<h5 class-options__heading="true">Quick Actions</h5>
Expand Down
4 changes: 2 additions & 2 deletions packages/klighd-interactive/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"dependencies": {
"inversify": "^6.0.2",
"snabbdom": "^3.5.1",
"sprotty": "^1.1.0",
"sprotty-protocol": "^1.1.0"
"sprotty": "^1.3.0",
"sprotty-protocol": "^1.3.0"
},
"devDependencies": {
"rimraf": "^4.4.0",
Expand Down
Loading
Loading