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 <title> 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 <g>', 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 <title>', 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); + }); + }); });