mirror of
https://github.com/hcengineering/platform.git
synced 2025-05-31 04:38:02 +00:00
181 lines
6.0 KiB
Svelte
181 lines
6.0 KiB
Svelte
<!--
|
|
// Copyright © 2020, 2021 Anticrm Platform Contributors.
|
|
// Copyright © 2021 Hardcore Engineering Inc.
|
|
//
|
|
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License. You may
|
|
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
//
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
-->
|
|
<script lang="ts">
|
|
import { CheckBox, Component, navigate, parseLocation } from '@hcengineering/ui'
|
|
import view from '@hcengineering/view'
|
|
|
|
export let nodes: NodeListOf<any>
|
|
|
|
function prevName (pos: number, nodes: NodeListOf<any>): string | undefined {
|
|
while (true) {
|
|
if (nodes[pos - 1]?.nodeName === '#text' && (nodes[pos - 1]?.data ?? '').trim() === '') {
|
|
pos--
|
|
continue
|
|
}
|
|
break
|
|
}
|
|
return nodes[pos - 1]?.nodeName
|
|
}
|
|
</script>
|
|
|
|
{#if nodes}
|
|
{#each nodes as node, ni}
|
|
{#if node.nodeType === Node.TEXT_NODE}
|
|
{node.data}
|
|
{:else if node.nodeName === 'EM'}
|
|
<em><svelte:self nodes={node.childNodes} /></em>
|
|
{:else if node.nodeName === 'STRONG' || node.nodeName === 'B'}
|
|
<strong><svelte:self nodes={node.childNodes} /></strong>
|
|
{:else if node.nodeName === 'P'}
|
|
{#if node.childNodes.length > 0}
|
|
<p class="p-inline contrast">
|
|
<svelte:self nodes={node.childNodes} />
|
|
</p>
|
|
{/if}
|
|
{:else if node.nodeName === 'BLOCKQUOTE'}
|
|
<blockquote><svelte:self nodes={node.childNodes} /></blockquote>
|
|
{:else if node.nodeName === 'CODE'}
|
|
<code><svelte:self nodes={node.childNodes} /></code>
|
|
{:else if node.nodeName === 'PRE'}
|
|
<pre><svelte:self nodes={node.childNodes} /></pre>
|
|
{:else if node.nodeName === 'BR'}
|
|
{@const pName = prevName(ni, nodes)}
|
|
{#if pName !== 'P' && pName !== 'BR' && pName !== undefined}
|
|
<br />
|
|
{/if}
|
|
{:else if node.nodeName === 'HR'}
|
|
<hr />
|
|
{:else if node.nodeName === 'IMG'}
|
|
<div class="max-h-60 max-w-60">{@html node.outerHTML}</div>
|
|
{:else if node.nodeName === 'H1'}
|
|
<h1><svelte:self nodes={node.childNodes} /></h1>
|
|
{:else if node.nodeName === 'H2'}
|
|
<h2><svelte:self nodes={node.childNodes} /></h2>
|
|
{:else if node.nodeName === 'H3'}
|
|
<h3><svelte:self nodes={node.childNodes} /></h3>
|
|
{:else if node.nodeName === 'H4'}
|
|
<h4><svelte:self nodes={node.childNodes} /></h4>
|
|
{:else if node.nodeName === 'H5'}
|
|
<h5><svelte:self nodes={node.childNodes} /></h5>
|
|
{:else if node.nodeName === 'H6'}
|
|
<h6><svelte:self nodes={node.childNodes} /></h6>
|
|
{:else if node.nodeName === 'UL' || node.nodeName === 'LIST'}
|
|
<ul><svelte:self nodes={node.childNodes} /></ul>
|
|
{:else if node.nodeName === 'OL' || node.nodeName === 'LIST=1'}
|
|
<ol><svelte:self nodes={node.childNodes} /></ol>
|
|
{:else if node.nodeName === 'LI'}
|
|
<li class={node.className}><svelte:self nodes={node.childNodes} /></li>
|
|
{:else if node.nodeName === 'DIV'}
|
|
<div><svelte:self nodes={node.childNodes} /></div>
|
|
{:else if node.nodeName === 'A'}
|
|
<a
|
|
href={node.getAttribute('href')}
|
|
target={node.getAttribute('target')}
|
|
on:click={(e) => {
|
|
try {
|
|
const url = new URL(node.getAttribute('href'))
|
|
|
|
if (url.origin === window.location.origin) {
|
|
e.preventDefault()
|
|
navigate(parseLocation(url))
|
|
}
|
|
} catch {}
|
|
}}><svelte:self nodes={node.childNodes} /></a
|
|
>
|
|
{:else if node.nodeName === 'LABEL'}
|
|
<svelte:self nodes={node.childNodes} />
|
|
{:else if node.nodeName === 'INPUT'}
|
|
{#if node.type?.toLowerCase() === 'checkbox'}
|
|
<div class="checkboxContainer">
|
|
<CheckBox readonly checked={node.checked} />
|
|
</div>
|
|
{/if}
|
|
{:else if node.nodeName === 'SPAN'}
|
|
<span style:margin={'0 .25rem'} style={node.getAttribute('style')}>
|
|
<!-- <svelte:self nodes={node.childNodes} /> -->
|
|
{#if node.getAttribute('data-objectclass') !== undefined && node.getAttribute('data-id') !== undefined}
|
|
<Component
|
|
is={view.component.ObjectPresenter}
|
|
inline
|
|
props={{
|
|
objectId: node.getAttribute('data-id'),
|
|
title: node.getAttribute('data-label'),
|
|
_class: node.getAttribute('data-objectclass'),
|
|
inline: true
|
|
}}
|
|
/>
|
|
{:else}
|
|
<svelte:self nodes={node.childNodes} />
|
|
{/if}
|
|
</span>
|
|
{:else if node.nodeName === 'TABLE'}
|
|
<table class={node.className}><svelte:self nodes={node.childNodes} /></table>
|
|
{:else if node.nodeName === 'TBODY'}
|
|
<tbody><svelte:self nodes={node.childNodes} /></tbody>
|
|
{:else if node.nodeName === 'TR'}
|
|
<tr><svelte:self nodes={node.childNodes} /></tr>
|
|
{:else if node.nodeName === 'TH'}
|
|
<th><svelte:self nodes={node.childNodes} /></th>
|
|
{:else if node.nodeName === 'TD'}
|
|
<td><svelte:self nodes={node.childNodes} /></td>
|
|
{:else if node.nodeName === 'S'}
|
|
<s><svelte:self nodes={node.childNodes} /></s>
|
|
{:else}
|
|
unknown: "{node.nodeName}"
|
|
<svelte:self nodes={node.childNodes} />
|
|
{/if}
|
|
{/each}
|
|
{/if}
|
|
|
|
<style lang="scss">
|
|
.img {
|
|
:global(img) {
|
|
object-fit: contain;
|
|
height: 100%;
|
|
width: 100%;
|
|
}
|
|
}
|
|
|
|
.checkboxContainer {
|
|
padding-top: 0.125rem;
|
|
}
|
|
|
|
em,
|
|
strong,
|
|
blockquote,
|
|
pre,
|
|
h1,
|
|
h2,
|
|
h3,
|
|
h4,
|
|
h5,
|
|
h6,
|
|
ol,
|
|
li,
|
|
.checkboxContainer,
|
|
s {
|
|
color: var(--theme-accent-color);
|
|
}
|
|
code {
|
|
padding: 0 0.25rem;
|
|
font-family: var(--mono-font);
|
|
color: var(--theme-code-color);
|
|
background-color: var(--theme-button-enabled);
|
|
border: 1px solid var(--theme-button-border);
|
|
border-radius: 0.25rem;
|
|
}
|
|
</style>
|