diff --git a/modules/helfi_toc/assets/js/tableOfContents.js b/modules/helfi_toc/assets/js/tableOfContents.js index 634903968..226b24b93 100644 --- a/modules/helfi_toc/assets/js/tableOfContents.js +++ b/modules/helfi_toc/assets/js/tableOfContents.js @@ -1,21 +1,23 @@ 'use strict'; -(function (Drupal, once) { +(function (Drupal, once, drupalSettings) { Drupal.behaviors.table_of_contents = { attach: function attach() { function findAvailableId(name, reserved, anchors, count) { let newName = name; if (count > 0) { // Only when headings are not unique on page we want to add counter - newName += '-' + count; + newName += `-${count}`; } if (reserved.includes(newName)) { - return findAvailableId(name, reserved, anchors, ++count); - } else if (anchors.includes(newName)) { + return findAvailableId(name, reserved, anchors, count + 1); + } + + if (anchors.includes(newName)) { if (count === 0) { - count++; // When reserved heading is visible on page, lets start counting from 2 instead of 1 + count += 1; // When reserved heading is visible on page, lets start counting from 2 instead of 1 } - return findAvailableId(name, reserved, anchors, ++count); + return findAvailableId(name, reserved, anchors, count + 1); } return newName; } @@ -32,62 +34,149 @@ // Exclude elements from TOC that are not content: // e.g. TOC, sidebar, cookie compliency-banner etc. - const exclusions = '' + + const exclusions = + '' + ':not(.layout-sidebar-first *)' + ':not(.layout-sidebar-second *)' + ':not(.tools__container *)' + ':not(.breadcrumb__container *)' + ':not(#helfi-toc-table-of-contents *)' + ':not(.embedded-content-cookie-compliance *)' + - ':not(.react-and-share-cookie-compliance *)' + ':not(.react-and-share-cookie-compliance *)'; const titleComponents = [ - 'h2'+exclusions, - 'h3'+exclusions, - 'h4'+exclusions, - 'h5'+exclusions, - 'h6'+exclusions, + `h2${exclusions}`, + `h3${exclusions}`, + `h4${exclusions}`, + `h5${exclusions}`, + `h6${exclusions}`, + ]; + + const mainLanguages = [ + 'en', + 'fi', + 'sv', ]; + const swaps = { + '0': '[°₀۰0]', + '1': '[¹₁۱1]', + '2': '[²₂۲2]', + '3': '[³₃۳3]', + '4': '[⁴₄۴٤4]', + '5': '[⁵₅۵٥5]', + '6': '[⁶₆۶٦6]', + '7': '[⁷₇۷7]', + '8': '[⁸₈۸8]', + '9': '[⁹₉۹9]', + 'a': '[àáảãạăắằẳẵặâấầẩẫậāąåαάἀἁἂἃἄἅἆἇᾀᾁᾂᾃᾄᾅᾆᾇὰᾰᾱᾲᾳᾴᾶᾷаأအာါǻǎªაअاaä]', + 'b': '[бβبဗბbब]', + 'c': '[çćčĉċc©]', + 'd': '[ďðđƌȡɖɗᵭᶁᶑдδدضဍဒდdᴅᴆ]', + 'e': '[éèẻẽẹêếềểễệëēęěĕėεέἐἑἒἓἔἕὲеёэєəဧေဲეएإئe]', + 'f': '[фφفƒფf]', + 'g': '[ĝğġģгґγဂგگg]', + 'h': '[ĥħηήحهဟှჰh]', + 'i': '[íìỉĩịîïīĭįıιίϊΐἰἱἲἳἴἵἶἷὶῐῑῒῖῗіїиဣိီည်ǐიइیii̇ϒ]', + 'j': '[ĵјჯجj]', + 'k': '[ķĸкκقكကკქکk]', + 'l': '[łľĺļŀлλلလლlल]', + 'm': '[мμمမმm]', + 'n': '[ñńňņʼnŋνнنနნn]', + 'o': '[óòỏõọôốồổỗộơớờởỡợøōőŏοὀὁὂὃὄὅὸόоوθိုǒǿºოओoöө]', + 'p': '[пπပპپp]', + 'q': '[ყq]', + 'r': '[ŕřŗрρرრr]', + 's': '[śšşсσșςسصစſსsŝ]', + 't': '[ťţтτțتطဋတŧთტt]', + 'u': '[úùủũụưứừửữựûūůűŭųµуဉုူǔǖǘǚǜუउuўü]', + 'v': '[вვϐv]', + 'w': '[ŵωώဝွw]', + 'x': '[χξx]', + 'y': '[ýỳỷỹỵÿŷйыυϋύΰيယyῠῡὺ]', + 'z': '[źžżзζزဇზz]', + 'aa': '[عआآ]', + 'ae': '[æǽ]', + 'ai': '[ऐ]', + 'ch': '[чჩჭچ]', + 'dj': '[ђđ]', + 'dz': '[џძ]', + 'ei': '[ऍ]', + 'gh': '[غღ]', + 'ii': '[ई]', + 'ij': '[ij]', + 'kh': '[хخხ]', + 'lj': '[љ]', + 'nj': '[њ]', + 'oe': '[öœؤ]', + 'oi': '[ऑ]', + 'oii': '[ऒ]', + 'ps': '[ψ]', + 'sh': '[шშش]', + 'shch': '[щ]', + 'ss': '[ß]', + 'sx': '[ŝ]', + 'th': '[þϑثذظ]', + 'ts': '[цცწ]', + 'ue': '[ü]', + 'uu': '[ऊ]', + 'ya': '[я]', + 'yu': '[ю]', + 'zh': '[жჟژ]', + 'gx': '[ĝ]', + 'hx': '[ĥ]', + 'jx': '[ĵ]', + }; + // Craft table of contents. once('table-of-contents', titleComponents.join(','), mainContent) .forEach(function (content) { - const name = content.textContent + let name = content.textContent .toLowerCase() - .trim() - .replace(/ä/gi, 'a') - .replace(/ö/gi, 'o') - .replace(/å/gi, 'a') - .replace(/\W/g, '-') - .replace(/-(\d+)$/g, '_$1'); - - let nodeName = content.nodeName.toLowerCase(); - if (nodeName === 'button') { - nodeName = content.parentElement.nodeName.toLowerCase(); + .trim(); + + // To ensure backwards compatibility, this is done only to "other" languages. + if (!mainLanguages.includes(drupalSettings.path.currentLanguage)) { + Object.keys(swaps).forEach((swap) => { + name = name.replace(new RegExp(swaps[swap], 'g'), swap); + }); } + else { + name = name + .replace(/ä/gi, 'a') + .replace(/ö/gi, 'o') + .replace(/å/gi, 'a'); + } + + name = name.replace(/\W/g, '-').replace(/\s/g, '-').replace(/-(\d+)$/g, '_$1'); + + let nodeName = content.nodeName.toLowerCase(); + if (nodeName === 'button') { + nodeName = content.parentElement.nodeName.toLowerCase(); + } const anchorName = content.id ? content.id : findAvailableId(name, reserved, anchors, 0); - anchors.push(anchorName); + anchors.push(anchorName); - // Create table of contents if component is enabled. - if (tableOfContentsList && nodeName === "h2") { - let listItem = document.createElement('li'); - listItem.classList.add('table-of-contents__item'); + // Create table of contents if component is enabled. + if (tableOfContentsList && nodeName === 'h2') { + let listItem = document.createElement('li'); + listItem.classList.add('table-of-contents__item'); - let link = document.createElement('a'); - link.classList.add('table-of-contents__link'); - link.href = '#' + anchorName; - link.textContent = content.textContent.trim(); + let link = document.createElement('a'); + link.classList.add('table-of-contents__link'); + link.href = `#${anchorName}`; + link.textContent = content.textContent.trim(); - listItem.appendChild(link); - tableOfContentsList.appendChild(listItem); - } - // Create anchor links. - content.setAttribute('id', anchorName); - }); + listItem.appendChild(link); + tableOfContentsList.appendChild(listItem); + } + // Create anchor links. + content.setAttribute('id', anchorName); + }); // Remove loading text. if (tableOfContents) { @@ -98,4 +187,4 @@ } }, }; -})(Drupal, once); +})(Drupal, once, drupalSettings);