diff --git a/src/dia/attributes/index.mjs b/src/dia/attributes/index.mjs
index ef40450bd..aa6627c42 100644
--- a/src/dia/attributes/index.mjs
+++ b/src/dia/attributes/index.mjs
@@ -427,9 +427,14 @@ const attributesNS = {
var cache = $node.data(cacheName);
if (cache === undefined || cache !== title) {
$node.data(cacheName, title);
+ if (node.tagName === 'title') {
+ // The target node is a
element.
+ node.textContent = title;
+ return;
+ }
// Generally element should be the first child element of its parent.
- var firstChild = node.firstChild;
- if (firstChild && firstChild.tagName.toUpperCase() === 'TITLE') {
+ var firstChild = node.firstElementChild;
+ if (firstChild && firstChild.tagName === 'title') {
// Update an existing title
firstChild.textContent = title;
} else {
diff --git a/test/jointjs/dia/attributes.js b/test/jointjs/dia/attributes.js
index 45ffab36d..4d483441e 100644
--- a/test/jointjs/dia/attributes.js
+++ b/test/jointjs/dia/attributes.js
@@ -1054,5 +1054,77 @@ QUnit.module('Attributes', function() {
});
});
});
+
+ QUnit.module('Title Attribute', function(hooks) {
+
+ var paper, graph, cell, cellView;
+
+ hooks.beforeEach(function() {
+ graph = new joint.dia.Graph;
+ const fixtures = document.getElementById('qunit-fixture');
+ const paperEl = document.createElement('div');
+ fixtures.appendChild(paperEl);
+ paper = new joint.dia.Paper({ el: paperEl, model: graph });
+ cell = new joint.shapes.standard.Rectangle();
+ cell.addTo(graph);
+ cellView = cell.findView(paper);
+ });
+
+ hooks.afterEach(function() {
+ paper.remove();
+ });
+
+ QUnit.test('used on ', function(assert) {
+ let titleText;
+ assert.equal(cellView.el.querySelectorAll('title').length, 0);
+ titleText = 'test-title';
+ cell.attr('root/title', titleText);
+ assert.equal(cellView.el.querySelectorAll('title').length, 1);
+ assert.equal(cellView.el.firstChild.textContent, titleText);
+ titleText = 'test-title-2';
+ cell.attr('root/title', titleText);
+ assert.equal(cellView.el.querySelectorAll('title').length, 1);
+ assert.equal(cellView.el.firstChild.textContent, titleText);
+ });
+
+ QUnit.test('used on ', function(assert) {
+ let titleText;
+ cell.set('markup', [
+ { tagName: 'title', selector: 'title' },
+ { tagName: 'rect', selector: 'body' },
+ { tagName: 'text', selector: 'label' }
+ ]);
+ assert.equal(cellView.el.querySelectorAll('title').length, 1);
+ titleText = 'test-title';
+ cell.attr('title/title', titleText);
+ assert.equal(cellView.el.querySelectorAll('title').length, 1);
+ assert.equal(cellView.el.firstChild.textContent, titleText);
+ titleText = 'test-title-2';
+ cell.attr('title/title', titleText);
+ assert.equal(cellView.el.querySelectorAll('title').length, 1);
+ assert.equal(cellView.el.firstChild.textContent, titleText);
+ });
+
+ QUnit.test('used on element with text node', function(assert) {
+ let titleText;
+ const textNodeText = 'test-text-node';
+ cell.set('markup', [
+ textNodeText,
+ { tagName: 'rect', selector: 'body' },
+ { tagName: 'text', selector: 'label' }
+ ]);
+ assert.equal(cellView.el.querySelectorAll('title').length, 0);
+ titleText = 'test-title';
+ cell.attr('root/title', titleText);
+ assert.equal(cellView.el.querySelectorAll('title').length, 1);
+ assert.equal(cellView.el.firstChild.textContent, textNodeText);
+ assert.equal(cellView.el.firstElementChild.textContent, titleText);
+ titleText = 'test-title-2';
+ cell.attr('root/title', titleText);
+ assert.equal(cellView.el.querySelectorAll('title').length, 1);
+ assert.equal(cellView.el.firstChild.textContent, textNodeText);
+ assert.equal(cellView.el.firstElementChild.textContent, titleText);
+ });
+ });
});