mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Showing links in text cells
Summary: When there is a link in a text cell (and formula cells), it will be rendered with a little clickable icon wrapped in the anchor tag with a proper link. Only links that starts with https? will be rendered as links. Links are shown in a Text and Formula fields, inside a GridView, CardView and in the Import preview dialog. Test Plan: Browser tests Reviewers: alexmojaki Reviewed By: alexmojaki Subscribers: dsagal, alexmojaki Differential Revision: https://phab.getgrist.com/D3070
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
import {CellValue} from 'app/common/DocActions';
|
||||
import {DataRowModel} from 'app/client/models/DataRowModel';
|
||||
import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
|
||||
import {colors, testId} from 'app/client/ui2018/cssVars';
|
||||
import {icon} from 'app/client/ui2018/icons';
|
||||
import {NTextBox} from 'app/client/widgets/NTextBox';
|
||||
import {dom, styled} from 'grainjs';
|
||||
import {constructUrl, sameDocumentUrlState, urlState} from "app/client/models/gristUrlState";
|
||||
import { DataRowModel } from 'app/client/models/DataRowModel';
|
||||
import { ViewFieldRec } from 'app/client/models/entities/ViewFieldRec';
|
||||
import { constructUrl } from 'app/client/models/gristUrlState';
|
||||
import { colors, testId } from 'app/client/ui2018/cssVars';
|
||||
import { cssIconBackground, icon } from 'app/client/ui2018/icons';
|
||||
import { gristLink } from 'app/client/ui2018/links';
|
||||
import { cssHoverIn, NTextBox } from 'app/client/widgets/NTextBox';
|
||||
import { CellValue } from 'app/common/DocActions';
|
||||
import { Computed, dom, styled } from 'grainjs';
|
||||
|
||||
/**
|
||||
* Creates a widget for displaying links. Links can entered directly or following a title.
|
||||
@@ -19,22 +20,19 @@ export class HyperLinkTextBox extends NTextBox {
|
||||
|
||||
public buildDom(row: DataRowModel) {
|
||||
const value = row.cells[this.field.colId()];
|
||||
const url = Computed.create(null, (use) => constructUrl(use(value)));
|
||||
return cssFieldClip(
|
||||
dom.autoDispose(url),
|
||||
dom.style('text-align', this.alignment),
|
||||
dom.cls('text_wrapping', this.wrapping),
|
||||
dom.maybe((use) => Boolean(use(value)), () =>
|
||||
dom('a',
|
||||
dom.attr('href', (use) => constructUrl(use(value))),
|
||||
dom.attr('target', '_blank'),
|
||||
dom.on('click', (ev) =>
|
||||
_onClickHyperlink(ev, value.peek())),
|
||||
// As per Google and Mozilla recommendations to prevent opened links
|
||||
// from running on the same process as Grist:
|
||||
// https://developers.google.com/web/tools/lighthouse/audits/noopener
|
||||
dom.attr('rel', 'noopener noreferrer'),
|
||||
cssLinkIcon('FieldLink', testId('tb-link-icon')),
|
||||
testId('tb-link')
|
||||
)
|
||||
gristLink(url,
|
||||
cssIconBackground(
|
||||
icon("FieldLink", testId('tb-link-icon')),
|
||||
dom.cls(cssHoverOnField.className),
|
||||
),
|
||||
testId('tb-link'),
|
||||
),
|
||||
),
|
||||
dom.text((use) => _formatValue(use(value))),
|
||||
);
|
||||
@@ -50,26 +48,8 @@ function _formatValue(value: CellValue): string {
|
||||
return index >= 0 ? value.slice(0, index) : value;
|
||||
}
|
||||
|
||||
/**
|
||||
* If possible (i.e. if `url` points to somewhere in the current document)
|
||||
* use pushUrl to navigate without reloading or opening a new tab
|
||||
*/
|
||||
async function _onClickHyperlink(ev: MouseEvent, url: CellValue) {
|
||||
// Only override plain-vanilla clicks.
|
||||
if (ev.shiftKey || ev.metaKey || ev.ctrlKey || ev.altKey) { return; }
|
||||
|
||||
const newUrlState = sameDocumentUrlState(url);
|
||||
if (!newUrlState) { return; }
|
||||
|
||||
ev.preventDefault();
|
||||
await urlState().pushUrl(newUrlState);
|
||||
}
|
||||
|
||||
const cssFieldClip = styled('div.field_clip', `
|
||||
color: var(--grist-actual-cell-color, ${colors.lightGreen});
|
||||
`);
|
||||
|
||||
const cssLinkIcon = styled(icon, `
|
||||
background-color: var(--grist-actual-cell-color, ${colors.lightGreen});
|
||||
margin: -1px 2px 2px 0;
|
||||
`);
|
||||
const cssHoverOnField = cssHoverIn(cssFieldClip.className);
|
||||
|
||||
Reference in New Issue
Block a user