diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index 020bca659927..cdbd3db3b195 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -186,12 +186,94 @@ ajaxify = window.ajaxify || {}; $('#content, #footer').removeClass('ajaxifying'); // Only executed on ajaxify. Otherwise these'd be in ajaxify.end() - app.refreshTitle(data.title); - app.updateTags(); + updateTitle(data.title); + updateTags(); }); }); } + function updateTitle(title) { + if (!title) { + return; + } + require(['translator'], function (translator) { + title = config.titleLayout.replace(/{/g, '{').replace(/}/g, '}') + .replace('{pageTitle}', function () { return title; }) + .replace('{browserTitle}', function () { return config.browserTitle; }); + + // Allow translation strings in title on ajaxify (#5927) + title = translator.unescape(title); + + translator.translate(title, function (translated) { + window.document.title = $('
').html(translated).text(); + }); + }); + } + + function updateTags() { + var metaWhitelist = ['title', 'description', /og:.+/, /article:.+/].map(function (val) { + return new RegExp(val); + }); + var linkWhitelist = ['canonical', 'alternate', 'up']; + + // Delete the old meta tags + Array.prototype.slice + .call(document.querySelectorAll('head meta')) + .filter(function (el) { + var name = el.getAttribute('property') || el.getAttribute('name'); + return metaWhitelist.some(function (exp) { + return !!exp.test(name); + }); + }) + .forEach(function (el) { + document.head.removeChild(el); + }); + + // Add new meta tags + ajaxify.data._header.tags.meta + .filter(function (tagObj) { + var name = tagObj.name || tagObj.property; + return metaWhitelist.some(function (exp) { + return !!exp.test(name); + }); + }) + .forEach(function (tagObj) { + var metaEl = document.createElement('meta'); + Object.keys(tagObj).forEach(function (prop) { + metaEl.setAttribute(prop, tagObj[prop]); + }); + document.head.appendChild(metaEl); + }); + + // Delete the old link tags + Array.prototype.slice + .call(document.querySelectorAll('head link')) + .filter(function (el) { + var name = el.getAttribute('rel'); + return linkWhitelist.some(function (item) { + return item === name; + }); + }) + .forEach(function (el) { + document.head.removeChild(el); + }); + + // Add new link tags + ajaxify.data._header.tags.link + .filter(function (tagObj) { + return linkWhitelist.some(function (item) { + return item === tagObj.rel; + }); + }) + .forEach(function (tagObj) { + var linkEl = document.createElement('link'); + Object.keys(tagObj).forEach(function (prop) { + linkEl.setAttribute(prop, tagObj[prop]); + }); + document.head.appendChild(linkEl); + }); + } + ajaxify.end = function (url, tpl_url) { ajaxify.loadScript(tpl_url, function done() { $(window).trigger('action:ajaxify.end', { url: url, tpl_url: tpl_url, title: ajaxify.data.title }); diff --git a/public/src/app.js b/public/src/app.js index d64f81ce00ac..587b57b428b0 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -46,40 +46,13 @@ app.cacheBuster = null; }); Visibility.change(function (event, state) { - if (state === 'visible') { - app.isFocused = true; - app.alternatingTitle(''); - } else if (state === 'hidden') { - app.isFocused = false; - } + app.isFocused = state === 'visible'; }); createHeaderTooltips(); app.showEmailConfirmWarning(); app.showCookieWarning(); - socket.removeAllListeners('event:nodebb.ready'); - socket.on('event:nodebb.ready', function (data) { - if ((data.hostname === app.upstreamHost) && (!app.cacheBuster || app.cacheBuster !== data['cache-buster'])) { - app.cacheBuster = data['cache-buster']; - - app.alert({ - alert_id: 'forum_updated', - title: '[[global:updated.title]]', - message: '[[global:updated.message]]', - clickfn: function () { - window.location.reload(); - }, - type: 'warning', - }); - } - }); - socket.on('event:livereload', function () { - if (app.user.isAdmin && !ajaxify.currentPage.match(/admin/)) { - window.location.reload(); - } - }); - require(['taskbar', 'helpers', 'forum/pagination'], function (taskbar, helpers, pagination) { taskbar.init(); @@ -374,66 +347,6 @@ app.cacheBuster = null; }); }; - var titleObj = { - active: false, - interval: undefined, - titles: [], - }; - - app.alternatingTitle = function (title) { - if (typeof title !== 'string') { - return; - } - - if (title.length > 0 && !app.isFocused) { - if (!titleObj.titles[0]) { - titleObj.titles[0] = window.document.title; - } - - require(['translator'], function (translator) { - translator.translate(title, function (translated) { - titleObj.titles[1] = translated; - if (titleObj.interval) { - clearInterval(titleObj.interval); - } - - titleObj.interval = setInterval(function () { - var title = titleObj.titles[titleObj.titles.indexOf(window.document.title) ^ 1]; - if (title) { - window.document.title = $('
').html(title).text(); - } - }, 2000); - }); - }); - } else { - if (titleObj.interval) { - clearInterval(titleObj.interval); - } - if (titleObj.titles[0]) { - window.document.title = $('
').html(titleObj.titles[0]).text(); - } - } - }; - - app.refreshTitle = function (title) { - if (!title) { - return; - } - require(['translator'], function (translator) { - title = config.titleLayout.replace(/{/g, '{').replace(/}/g, '}') - .replace('{pageTitle}', function () { return title; }) - .replace('{browserTitle}', function () { return config.browserTitle; }); - - // Allow translation strings in title on ajaxify (#5927) - title = translator.unescape(title); - - translator.translate(title, function (translated) { - titleObj.titles[0] = translated; - app.alternatingTitle(''); - }); - }); - }; - app.toggleNavbar = function (state) { var navbarEl = $('.navbar'); if (navbarEl) { @@ -767,105 +680,4 @@ app.cacheBuster = null; }); }); }; - - app.reskin = function (skinName) { - var clientEl = Array.prototype.filter.call(document.querySelectorAll('link[rel="stylesheet"]'), function (el) { - return el.href.indexOf(config.relative_path + '/assets/client') !== -1; - })[0] || null; - if (!clientEl) { - return; - } - - var currentSkinClassName = $('body').attr('class').split(/\s+/).filter(function (className) { - return className.startsWith('skin-'); - }); - if (!currentSkinClassName[0]) { - return; - } - var currentSkin = currentSkinClassName[0].slice(5); - currentSkin = currentSkin !== 'noskin' ? currentSkin : ''; - - // Stop execution if skin didn't change - if (skinName === currentSkin) { - return; - } - - var linkEl = document.createElement('link'); - linkEl.rel = 'stylesheet'; - linkEl.type = 'text/css'; - linkEl.href = config.relative_path + '/assets/client' + (skinName ? '-' + skinName : '') + '.css'; - linkEl.onload = function () { - clientEl.parentNode.removeChild(clientEl); - - // Update body class with proper skin name - $('body').removeClass(currentSkinClassName.join(' ')); - $('body').addClass('skin-' + (skinName || 'noskin')); - }; - - document.head.appendChild(linkEl); - }; - - app.updateTags = function () { - var metaWhitelist = ['title', 'description', /og:.+/, /article:.+/].map(function (val) { - return new RegExp(val); - }); - var linkWhitelist = ['canonical', 'alternate', 'up']; - - // Delete the old meta tags - Array.prototype.slice - .call(document.querySelectorAll('head meta')) - .filter(function (el) { - var name = el.getAttribute('property') || el.getAttribute('name'); - return metaWhitelist.some(function (exp) { - return !!exp.test(name); - }); - }) - .forEach(function (el) { - document.head.removeChild(el); - }); - - // Add new meta tags - ajaxify.data._header.tags.meta - .filter(function (tagObj) { - var name = tagObj.name || tagObj.property; - return metaWhitelist.some(function (exp) { - return !!exp.test(name); - }); - }) - .forEach(function (tagObj) { - var metaEl = document.createElement('meta'); - Object.keys(tagObj).forEach(function (prop) { - metaEl.setAttribute(prop, tagObj[prop]); - }); - document.head.appendChild(metaEl); - }); - - // Delete the old link tags - Array.prototype.slice - .call(document.querySelectorAll('head link')) - .filter(function (el) { - var name = el.getAttribute('rel'); - return linkWhitelist.some(function (item) { - return item === name; - }); - }) - .forEach(function (el) { - document.head.removeChild(el); - }); - - // Add new link tags - ajaxify.data._header.tags.link - .filter(function (tagObj) { - return linkWhitelist.some(function (item) { - return item === tagObj.rel; - }); - }) - .forEach(function (tagObj) { - var linkEl = document.createElement('link'); - Object.keys(tagObj).forEach(function (prop) { - linkEl.setAttribute(prop, tagObj[prop]); - }); - document.head.appendChild(linkEl); - }); - }; }()); diff --git a/public/src/client/account/settings.js b/public/src/client/account/settings.js index 595bd774e5db..4b5783f3ced4 100644 --- a/public/src/client/account/settings.js +++ b/public/src/client/account/settings.js @@ -7,7 +7,7 @@ define('forum/account/settings', ['forum/account/header', 'components', 'sounds' // If page skin is changed but not saved, switch the skin back $(window).on('action:ajaxify.start', function () { if (ajaxify.data.template.name === 'account/settings' && $('#bootswatchSkin').val() !== config.bootswatchSkin) { - app.reskin(config.bootswatchSkin); + reskin(config.bootswatchSkin); } }); @@ -118,5 +118,42 @@ define('forum/account/settings', ['forum/account/header', 'components', 'sounds' } } + function reskin(skinName) { + var clientEl = Array.prototype.filter.call(document.querySelectorAll('link[rel="stylesheet"]'), function (el) { + return el.href.indexOf(config.relative_path + '/assets/client') !== -1; + })[0] || null; + if (!clientEl) { + return; + } + + var currentSkinClassName = $('body').attr('class').split(/\s+/).filter(function (className) { + return className.startsWith('skin-'); + }); + if (!currentSkinClassName[0]) { + return; + } + var currentSkin = currentSkinClassName[0].slice(5); + currentSkin = currentSkin !== 'noskin' ? currentSkin : ''; + + // Stop execution if skin didn't change + if (skinName === currentSkin) { + return; + } + + var linkEl = document.createElement('link'); + linkEl.rel = 'stylesheet'; + linkEl.type = 'text/css'; + linkEl.href = config.relative_path + '/assets/client' + (skinName ? '-' + skinName : '') + '.css'; + linkEl.onload = function () { + clientEl.parentNode.removeChild(clientEl); + + // Update body class with proper skin name + $('body').removeClass(currentSkinClassName.join(' ')); + $('body').addClass('skin-' + (skinName || 'noskin')); + }; + + document.head.appendChild(linkEl); + } + return AccountSettings; }); diff --git a/public/src/modules/chat.js b/public/src/modules/chat.js index 68e313181a43..ec33db51f73e 100644 --- a/public/src/modules/chat.js +++ b/public/src/modules/chat.js @@ -49,7 +49,6 @@ define('chat', [ module.onChatMessageReceived = function (data) { - var username = data.message.fromUser.username; var isSelf = data.self === 1; data.message.self = data.self; @@ -70,11 +69,7 @@ define('chat', [ roomData.silent = true; roomData.uid = app.user.uid; roomData.isSelf = isSelf; - module.createModal(roomData, function () { - if (!isSelf) { - updateTitleAndPlaySound(data.message.mid, username); - } - }); + module.createModal(roomData); }); } }; @@ -99,7 +94,6 @@ define('chat', [ } if (!isSelf && (!modal.is(':visible') || !app.isFocused)) { - updateTitleAndPlaySound(data.message.mid, username); taskbar.push('chat', modal.attr('data-uuid'), { title: '[[modules:chat.chatting_with]] ' + (data.roomName || username), touid: data.message.fromUser.uid, @@ -110,13 +104,6 @@ define('chat', [ }); } - function updateTitleAndPlaySound(mid, username) { - app.alternatingTitle('[[modules:chat.user_has_messaged_you, ' + username + ']]'); - require(['sounds'], function (sounds) { - sounds.play('chat-incoming', 'chat.incoming:' + mid); - }); - } - module.onUserStatusChange = function (data) { var modal = module.getModal(data.uid); app.updateUserStatus(modal.find('[component="user/status"]'), data.status); diff --git a/public/src/modules/taskbar.js b/public/src/modules/taskbar.js index 66eb2e4c88e9..15de6dce761d 100644 --- a/public/src/modules/taskbar.js +++ b/public/src/modules/taskbar.js @@ -22,7 +22,6 @@ define('taskbar', ['benchpress', 'translator'], function (Benchpress, translator minimizeAll(); module.load(uuid); taskbar.toggleNew(uuid, false); - app.alternatingTitle(''); taskbar.tasklist.removeClass('active'); $btn.addClass('active'); diff --git a/public/src/sockets.js b/public/src/sockets.js index f28d20cec81b..0d2c61dc1de3 100644 --- a/public/src/sockets.js +++ b/public/src/sockets.js @@ -72,6 +72,28 @@ socket = window.socket; socket.on('event:alert', function (params) { app.alert(params); }); + + socket.removeAllListeners('event:nodebb.ready'); + socket.on('event:nodebb.ready', function (data) { + if ((data.hostname === app.upstreamHost) && (!app.cacheBuster || app.cacheBuster !== data['cache-buster'])) { + app.cacheBuster = data['cache-buster']; + + app.alert({ + alert_id: 'forum_updated', + title: '[[global:updated.title]]', + message: '[[global:updated.message]]', + clickfn: function () { + window.location.reload(); + }, + type: 'warning', + }); + } + }); + socket.on('event:livereload', function () { + if (app.user.isAdmin && !ajaxify.currentPage.match(/admin/)) { + window.location.reload(); + } + }); } function onConnect() {