UNPKG

6.41 kBJavaScriptView Raw
1/*
2* Copyright (C) 1998-2021 by Northwoods Software Corporation. All Rights Reserved.
3*/
4/*
5* This is an extension and not part of the main GoJS library.
6* Note that the API for this class may change with any version, even point releases.
7* If you intend to use an extension in production, you should copy the code to your own source directory.
8* Extensions can be found in the GoJS kit under the extensions or extensionsTS folders.
9* See the Extensions intro page (https://gojs.net/latest/intro/extensions.html) for more information.
10*/
11import * as go from '../release/go-module.js';
12// A "HyperlinkText" is either a TextBlock or a Panel containing a TextBlock that when clicked
13// opens a new browser window with a given or computed URL.
14// When the user's mouse passes over a "HyperlinkText", the text is underlined.
15// When the mouse hovers over a "HyperlinkText", it shows a tooltip that displays the URL.
16// This "HyperlinkText" builder is not pre-defined in the GoJS library, so you will need to load this definition.
17// Typical usages:
18// $("HyperlinkText", "https://gojs.net", "Visit GoJS")
19//
20// $("HyperlinkText",
21// function(node) { return "https://gojs.net/" + node.data.version; },
22// function(node) { return "Visit GoJS version " + node.data.version; })
23//
24// $("HyperlinkText",
25// function(node) { return "https://gojs.net/" + node.data.version; },
26// $(go.Panel, "Auto",
27// $(go.Shape, ...),
28// $(go.TextBlock, ...)
29// )
30// )
31// The first argument to the "HyperlinkText" builder should be either the URL string or a function
32// that takes the data-bound Panel and returns the URL string.
33// If the URL string is empty or if the function returns an empty string,
34// the text will not be underlined on a mouse-over and a click has no effect.
35// The second argument to the "HyperlinkText" builder may be either a string to display in a TextBlock,
36// or a function that takes the data-bound Panel and returns the string to display in a TextBlock.
37// If no text string or function is provided, it assumes all of the arguments are used to
38// define the visual tree for the "HyperlinkText", in the normal fashion for a Panel.
39// The result is either a TextBlock or a Panel.
40go.GraphObject.defineBuilder('HyperlinkText', (args) => {
41 // the URL is required as the first argument, either a string or a side-effect-free function returning a string
42 const url = go.GraphObject.takeBuilderArgument(args, undefined, (x) => typeof x === 'string' || typeof x === 'function');
43 // the text for the HyperlinkText is the optional second argument, either a string or a side-effect-free function returning a string
44 let text = go.GraphObject.takeBuilderArgument(args, null, (x) => typeof x === 'string' || typeof x === 'function');
45 // see if the visual tree is supplied in the arguments to the "HyperlinkText"
46 let anyGraphObjects = false;
47 for (let i = 0; i < args.length; i++) {
48 const a = args[i];
49 if (a && a instanceof go.GraphObject)
50 anyGraphObjects = true;
51 }
52 // define the click behavior
53 const click = (e, obj) => {
54 let u = obj._url;
55 if (typeof u === 'function')
56 u = u(obj.findTemplateBinder());
57 if (u)
58 window.open(u, '_blank');
59 };
60 // define the tooltip
61 const tooltip = go.GraphObject.make('ToolTip', go.GraphObject.make(go.TextBlock, { name: 'TB', margin: 4 }, new go.Binding('text', '', function (obj) {
62 // here OBJ will be in the Adornment, need to get the HyperlinkText/TextBlock
63 obj = obj.part.adornedObject;
64 let u = obj._url;
65 if (typeof u === 'function')
66 u = u(obj.findTemplateBinder());
67 return u;
68 }).ofObject()), new go.Binding('visible', 'text', function (t) { return !!t; }).ofObject('TB'));
69 // if the text is provided, use a new TextBlock; otherwise assume the TextBlock is provided
70 if (typeof (text) === 'string' || typeof (text) === 'function' || !anyGraphObjects) {
71 if (text === null && typeof (url) === 'string')
72 text = url;
73 const tb = go.GraphObject.make(go.TextBlock, {
74 '_url': url,
75 cursor: 'pointer',
76 mouseEnter: function (e, obj) {
77 let u = obj._url;
78 if (typeof u === 'function')
79 u = u(obj.findTemplateBinder());
80 if (u && obj instanceof go.TextBlock)
81 obj.isUnderline = true;
82 },
83 mouseLeave: (e, obj) => { if (obj instanceof go.TextBlock)
84 obj.isUnderline = false; },
85 click: click,
86 toolTip: tooltip // shared by all HyperlinkText textblocks
87 });
88 if (typeof (text) === 'string') {
89 tb.text = text;
90 }
91 else if (typeof (text) === 'function') {
92 tb.bind(new go.Binding('text', '', text).ofObject());
93 }
94 else if (typeof (url) === 'function') {
95 tb.bind(new go.Binding('text', '', url).ofObject());
96 }
97 return tb;
98 }
99 else {
100 const findTextBlock = function (obj) {
101 if (obj instanceof go.TextBlock)
102 return obj;
103 if (obj instanceof go.Panel) {
104 const it = obj.elements;
105 while (it.next()) {
106 const result = findTextBlock(it.value);
107 if (result !== null)
108 return result;
109 }
110 }
111 return null;
112 };
113 return go.GraphObject.make(go.Panel, {
114 '_url': url,
115 cursor: 'pointer',
116 mouseEnter: (e, panel) => {
117 const tb = findTextBlock(panel);
118 let u = panel._url;
119 if (typeof u === 'function')
120 u = u(panel.findTemplateBinder());
121 if (tb !== null && u)
122 tb.isUnderline = true;
123 },
124 mouseLeave: (e, panel) => {
125 const tb = findTextBlock(panel);
126 if (tb !== null)
127 tb.isUnderline = false;
128 },
129 click: click,
130 toolTip: tooltip // shared by all HyperlinkText panels
131 });
132 }
133});