diff --git a/d2compiler/compile.go b/d2compiler/compile.go
index 0654e1567..ccfda366f 100644
--- a/d2compiler/compile.go
+++ b/d2compiler/compile.go
@@ -363,6 +363,14 @@ func (c *compiler) compileReserved(attrs *d2graph.Attributes, f *d2ir.Field) {
attrs.Constraint.Value = scalar.ScalarString()
attrs.Constraint.MapKey = f.LastPrimaryKey()
}
+
+ if attrs.Link != nil && attrs.Tooltip != nil {
+ _, err := url.ParseRequestURI(attrs.Tooltip.Value)
+ if err == nil {
+ c.errorf(scalar, "Tooltip cannot be an URL when Link is set")
+ }
+ }
+
}
func (c *compiler) compileStyle(attrs *d2graph.Attributes, m *d2ir.Map) {
diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go
index 584dd5115..ac30ae7f3 100644
--- a/d2compiler/compile_test.go
+++ b/d2compiler/compile_test.go
@@ -1457,6 +1457,40 @@ x -> y: {
}
},
},
+ {
+ name: "url_tooltip",
+ text: `x: {tooltip: https://google.com}`,
+ assertions: func(t *testing.T, g *d2graph.Graph) {
+ if len(g.Objects) != 1 {
+ t.Fatal(g.Objects)
+ }
+
+ if g.Objects[0].Attributes.Tooltip.Value != "https://google.com" {
+ t.Fatal(g.Objects[0].Attributes.Tooltip.Value)
+ }
+ },
+ },
+ {
+ name: "no_url_link_and_url_tooltip_concurrently",
+ text: `x: {link: https://not-google.com; tooltip: https://google.com}`,
+ expErr: `d2/testdata/d2compiler/TestCompile/no_url_link_and_url_tooltip_concurrently.d2:1:44: Tooltip cannot be an URL when Link is set`,
+ },
+ {
+ name: "url_link_and_not_url_tooltip_concurrently",
+ text: `x: {link: https://google.com; tooltip: hello world}`,
+ assertions: func(t *testing.T, g *d2graph.Graph) {
+ if len(g.Objects) != 1 {
+ t.Fatal(g.Objects)
+ }
+ if g.Objects[0].Attributes.Link.Value != "https://google.com" {
+ t.Fatal(g.Objects[0].Attributes.Link.Value)
+ }
+
+ if g.Objects[0].Attributes.Tooltip.Value != "hello world" {
+ t.Fatal(g.Objects[0].Attributes.Tooltip.Value)
+ }
+ },
+ },
{
name: "nil_scope_obj_regression",
diff --git a/d2renderers/d2sketch/testdata/animated/sketch.exp.svg b/d2renderers/d2sketch/testdata/animated/sketch.exp.svg
index 5436e2231..becd23be5 100644
--- a/d2renderers/d2sketch/testdata/animated/sketch.exp.svg
+++ b/d2renderers/d2sketch/testdata/animated/sketch.exp.svg
@@ -110,7 +110,7 @@
-wintersummertreessnowsun
+wintersummertreessnowsun
\ No newline at end of file
diff --git a/d2renderers/d2sketch/testdata/animated_dark/sketch.exp.svg b/d2renderers/d2sketch/testdata/animated_dark/sketch.exp.svg
index 94d2f4ef0..52de585df 100644
--- a/d2renderers/d2sketch/testdata/animated_dark/sketch.exp.svg
+++ b/d2renderers/d2sketch/testdata/animated_dark/sketch.exp.svg
@@ -108,7 +108,7 @@
-wintersummertreessnowsun
+wintersummertreessnowsun
\ No newline at end of file
diff --git a/e2etests-cli/testdata/TestCLI_E2E/hello_world_png_sketch.exp.png b/e2etests-cli/testdata/TestCLI_E2E/hello_world_png_sketch.exp.png
index 687d23c99..8ccb67e8e 100644
Binary files a/e2etests-cli/testdata/TestCLI_E2E/hello_world_png_sketch.exp.png and b/e2etests-cli/testdata/TestCLI_E2E/hello_world_png_sketch.exp.png differ
diff --git a/e2etests-cli/testdata/TestCLI_E2E/internal_linked_pdf.exp.pdf b/e2etests-cli/testdata/TestCLI_E2E/internal_linked_pdf.exp.pdf
index 9186410df..d57607674 100644
Binary files a/e2etests-cli/testdata/TestCLI_E2E/internal_linked_pdf.exp.pdf and b/e2etests-cli/testdata/TestCLI_E2E/internal_linked_pdf.exp.pdf differ
diff --git a/testdata/d2compiler/TestCompile/no_url_link_and_url_tooltip_concurrently.exp.json b/testdata/d2compiler/TestCompile/no_url_link_and_url_tooltip_concurrently.exp.json
new file mode 100644
index 000000000..d4c16cf4d
--- /dev/null
+++ b/testdata/d2compiler/TestCompile/no_url_link_and_url_tooltip_concurrently.exp.json
@@ -0,0 +1,12 @@
+{
+ "graph": null,
+ "err": {
+ "ioerr": null,
+ "errs": [
+ {
+ "range": "d2/testdata/d2compiler/TestCompile/no_url_link_and_url_tooltip_concurrently.d2,0:43:43-0:61:61",
+ "errmsg": "d2/testdata/d2compiler/TestCompile/no_url_link_and_url_tooltip_concurrently.d2:1:44: Tooltip cannot be an URL when Link is set"
+ }
+ ]
+ }
+}
diff --git a/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.exp.json b/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.exp.json
new file mode 100644
index 000000000..aeae7d1e2
--- /dev/null
+++ b/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.exp.json
@@ -0,0 +1,188 @@
+{
+ "graph": {
+ "name": "",
+ "isFolderOnly": false,
+ "ast": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.d2,0:0:0-0:51:51",
+ "nodes": [
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.d2,0:0:0-0:51:51",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.d2,0:0:0-0:1:1",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.d2,0:0:0-0:1:1",
+ "value": [
+ {
+ "string": "x",
+ "raw_string": "x"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "map": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.d2,0:3:3-0:50:50",
+ "nodes": [
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.d2,0:4:4-0:28:28",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.d2,0:4:4-0:8:8",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.d2,0:4:4-0:8:8",
+ "value": [
+ {
+ "string": "link",
+ "raw_string": "link"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.d2,0:10:10-0:28:28",
+ "value": [
+ {
+ "string": "https://google.com",
+ "raw_string": "https://google.com"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.d2,0:30:30-0:50:50",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.d2,0:30:30-0:37:37",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.d2,0:30:30-0:37:37",
+ "value": [
+ {
+ "string": "tooltip",
+ "raw_string": "tooltip"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.d2,0:39:39-0:50:50",
+ "value": [
+ {
+ "string": "hello world",
+ "raw_string": "hello world"
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+ },
+ "root": {
+ "id": "",
+ "id_val": "",
+ "label_dimensions": {
+ "width": 0,
+ "height": 0
+ },
+ "attributes": {
+ "label": {
+ "value": ""
+ },
+ "style": {},
+ "near_key": null,
+ "shape": {
+ "value": ""
+ },
+ "direction": {
+ "value": ""
+ },
+ "constraint": {
+ "value": ""
+ }
+ },
+ "zIndex": 0
+ },
+ "edges": null,
+ "objects": [
+ {
+ "id": "x",
+ "id_val": "x",
+ "label_dimensions": {
+ "width": 0,
+ "height": 0
+ },
+ "references": [
+ {
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.d2,0:0:0-0:1:1",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_link_and_not_url_tooltip_concurrently.d2,0:0:0-0:1:1",
+ "value": [
+ {
+ "string": "x",
+ "raw_string": "x"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "key_path_index": 0,
+ "map_key_edge_index": -1
+ }
+ ],
+ "attributes": {
+ "label": {
+ "value": "x"
+ },
+ "style": {},
+ "tooltip": {
+ "value": "hello world"
+ },
+ "link": {
+ "value": "https://google.com"
+ },
+ "near_key": null,
+ "shape": {
+ "value": "rectangle"
+ },
+ "direction": {
+ "value": ""
+ },
+ "constraint": {
+ "value": ""
+ }
+ },
+ "zIndex": 0
+ }
+ ]
+ },
+ "err": null
+}
diff --git a/testdata/d2compiler/TestCompile/url_tooltip.exp.json b/testdata/d2compiler/TestCompile/url_tooltip.exp.json
new file mode 100644
index 000000000..47234eb10
--- /dev/null
+++ b/testdata/d2compiler/TestCompile/url_tooltip.exp.json
@@ -0,0 +1,152 @@
+{
+ "graph": {
+ "name": "",
+ "isFolderOnly": false,
+ "ast": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_tooltip.d2,0:0:0-0:32:32",
+ "nodes": [
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_tooltip.d2,0:0:0-0:32:32",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_tooltip.d2,0:0:0-0:1:1",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_tooltip.d2,0:0:0-0:1:1",
+ "value": [
+ {
+ "string": "x",
+ "raw_string": "x"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "map": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_tooltip.d2,0:3:3-0:31:31",
+ "nodes": [
+ {
+ "map_key": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_tooltip.d2,0:4:4-0:31:31",
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_tooltip.d2,0:4:4-0:11:11",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_tooltip.d2,0:4:4-0:11:11",
+ "value": [
+ {
+ "string": "tooltip",
+ "raw_string": "tooltip"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "primary": {},
+ "value": {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_tooltip.d2,0:13:13-0:31:31",
+ "value": [
+ {
+ "string": "https://google.com",
+ "raw_string": "https://google.com"
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+ },
+ "root": {
+ "id": "",
+ "id_val": "",
+ "label_dimensions": {
+ "width": 0,
+ "height": 0
+ },
+ "attributes": {
+ "label": {
+ "value": ""
+ },
+ "style": {},
+ "near_key": null,
+ "shape": {
+ "value": ""
+ },
+ "direction": {
+ "value": ""
+ },
+ "constraint": {
+ "value": ""
+ }
+ },
+ "zIndex": 0
+ },
+ "edges": null,
+ "objects": [
+ {
+ "id": "x",
+ "id_val": "x",
+ "label_dimensions": {
+ "width": 0,
+ "height": 0
+ },
+ "references": [
+ {
+ "key": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_tooltip.d2,0:0:0-0:1:1",
+ "path": [
+ {
+ "unquoted_string": {
+ "range": "d2/testdata/d2compiler/TestCompile/url_tooltip.d2,0:0:0-0:1:1",
+ "value": [
+ {
+ "string": "x",
+ "raw_string": "x"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "key_path_index": 0,
+ "map_key_edge_index": -1
+ }
+ ],
+ "attributes": {
+ "label": {
+ "value": "x"
+ },
+ "style": {},
+ "tooltip": {
+ "value": "https://google.com"
+ },
+ "near_key": null,
+ "shape": {
+ "value": "rectangle"
+ },
+ "direction": {
+ "value": ""
+ },
+ "constraint": {
+ "value": ""
+ }
+ },
+ "zIndex": 0
+ }
+ ]
+ },
+ "err": null
+}