Skip to content

Commit

Permalink
Merge pull request #191 from kieler/nre/sprotty-1-3-0
Browse files Browse the repository at this point in the history
Update to Sprotty 1.3.0
  • Loading branch information
NiklasRentzCAU authored Aug 6, 2024
2 parents 4a3bb43 + 4874784 commit 6c8c06b
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 98 deletions.
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

0 comments on commit 6c8c06b

Please sign in to comment.