© Sergei Erjemin, 2009 — {% now 'Y' %}
{# #}
-
-
Google Analytics
-
{# #}
{# #}{# #}
+
{# #}
{# #}{# #}

{# #}
{# #}
-
- {##}
\ No newline at end of file
+ {##}
+
diff --git a/cadpoint/web/tests.py b/cadpoint/web/tests.py
index efa8c4a..df5414c 100644
--- a/cadpoint/web/tests.py
+++ b/cadpoint/web/tests.py
@@ -187,6 +187,24 @@ class AllTagsPageTests(TestCase):
self.assertContains(response, '
2')
self.assertContains(response, '
1')
+ def test_footer_counters_are_loaded_from_static_js(self):
+ response = self.client.get(reverse('web_alltags'))
+
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'js/footer-counters.js')
+ self.assertNotContains(response, 'googletagmanager.com/gtag/js?id=UA-9116991-1')
+ self.assertNotContains(response, 'mc.yandex.ru/metrika/tag.js')
+ self.assertNotContains(response, 'top-fwz1.mail.ru/js/code.js')
+
+ def test_accept_cookies_banner_loads_static_js(self):
+ response = self.client.get(reverse('web_alltags'))
+
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'js/accept-cookies.js')
+ self.assertContains(response, 'id="cookies_accept_button"')
+ self.assertNotContains(response, 'CookieAcceptDate = new Date()')
+ self.assertNotContains(response, 'onclick="CookieAcceptDate')
+
class TagEmptyStateTests(TestCase):
def setUp(self):
diff --git a/public/static/js/accept-cookies.js b/public/static/js/accept-cookies.js
new file mode 100644
index 0000000..51acec9
--- /dev/null
+++ b/public/static/js/accept-cookies.js
@@ -0,0 +1,39 @@
+(function (window, document) {
+ 'use strict';
+
+ // Защита от повторного подключения, если файл случайно вставят дважды.
+ if (window.__cadpointAcceptCookiesLoaded) {
+ return;
+ }
+ window.__cadpointAcceptCookiesLoaded = true;
+
+ var COOKIE_NAME = 'cookie_accept';
+ var COOKIE_VALUE = 'yes';
+ var COOKIE_TTL_MS = 7_948_800_000;
+ var bannerId = 'cookies_accept';
+ var buttonId = 'cookies_accept_button';
+
+ function acceptCookies() {
+ // Сохраняем согласие тем же ключом, что и раньше, чтобы серверная логика не менялась.
+ var cookieAcceptDate = new Date();
+ cookieAcceptDate.setTime(cookieAcceptDate.getTime() + COOKIE_TTL_MS);
+ document.cookie = COOKIE_NAME + '=' + COOKIE_VALUE + ';expires=' + cookieAcceptDate;
+
+ var banner = document.getElementById(bannerId);
+ if (banner) {
+ banner.remove();
+ }
+ }
+
+ function bindAcceptButton() {
+ var button = document.getElementById(buttonId);
+ if (!button) {
+ return;
+ }
+
+ button.addEventListener('click', acceptCookies);
+ }
+
+ bindAcceptButton();
+})(window, document);
+
diff --git a/public/static/js/footer-counters.js b/public/static/js/footer-counters.js
new file mode 100644
index 0000000..a4fb994
--- /dev/null
+++ b/public/static/js/footer-counters.js
@@ -0,0 +1,67 @@
+(function (window, document) {
+ 'use strict';
+
+ // Защита от повторной инициализации, если файл случайно подключат дважды.
+ if (window.__cadpointFooterCountersLoaded) {
+ return;
+ }
+ window.__cadpointFooterCountersLoaded = true;
+
+ function appendScript(src, id) {
+ // Не создаём дубликаты, если скрипт уже есть в DOM.
+ if (id && document.getElementById(id)) {
+ return null;
+ }
+ var script = document.createElement('script');
+ script.async = true;
+ script.src = src;
+ if (id) {
+ script.id = id;
+ }
+ (document.head || document.body).appendChild(script);
+ return script;
+ }
+ function initGoogleAnalytics() {
+ // Поддерживаем старый UA-код, чтобы не ломать текущую статистику.
+ window.dataLayer = window.dataLayer || [];
+ window.gtag = window.gtag || function gtag() {
+ window.dataLayer.push(arguments);
+ };
+ window.gtag('js', new Date());
+ window.gtag('config', 'UA-9116991-1');
+ appendScript('https://www.googletagmanager.com/gtag/js?id=UA-9116991-1', 'cadpoint-gtag-js');
+ }
+
+ function initYandexMetrika() {
+ // Повторяем стандартный паттерн Metrika: сначала очередь вызовов, потом загрузка внешнего файла.
+ window.ym = window.ym || function ym() {
+ (window.ym.a = window.ym.a || []).push(arguments);
+ };
+ window.ym.l = 1 * new Date();
+ window.ym(198477, 'init', {
+ clickmap: true,
+ trackLinks: true,
+ accurateTrackBounce: true,
+ webvisor: true,
+ });
+ appendScript('https://mc.yandex.ru/metrika/tag.js', 'cadpoint-yandex-metrika-js');
+ }
+
+ function initMailRuCounter() {
+ // Rating Mail.ru тоже любит сначала получить очередь событий, а затем уже внешний код.
+ window._tmr = window._tmr || [];
+ window._tmr.push({
+ id: '1612438',
+ type: 'pageView',
+ start: (new Date()).getTime(),
+ });
+ appendScript('https://top-fwz1.mail.ru/js/code.js', 'topmailru-code');
+ }
+
+ // Вызываем функции-счетчики
+ initGoogleAnalytics();
+ initYandexMetrika();
+ initMailRuCounter();
+
+})(window, document);
+