PageSourceSearch

https://www.bankofcanada.ca/wp-content/themes/parent-build/js/theme-switch.js?dts=20260408190432

js bankofcanada.ca collected 2026-09-24 07:50:19 UTC 7,031 bytes, 207 lines download raw bytes

1/*global AmCharts, storageAvailable*/
2
3let siteTheme = {
4
5    /**
6     * The current site theme
7     */
8    currentTheme: 'light',
9
10    /**
11     * Themes available for the site
12     */
13    availableThemes: ['light', 'dark'],
14
15    /**
16     * Selector for theme switcher
17     */
18    themeSwitcherSelector: '[data-action="theme-switch"]',
19
20    /**
21     * Theme Switcher object
22     */
23    $themeSwitcherObject: null,
24
25    /**
26     * The selector the for the twitter objects
27     */
28    twitterSelector: '.twitter-tweet',
29
30    /**
31     * Sets the value of 'data-theme' based on user preferences. This function is called when no 'theme' variable is found
32     * on local storage.
33     * @param {string}themeSwitcherHtmlId Html ID for the theme switcher
34     * @returns {void}
35     */
36    initializeSwitcher: function () {
37        // Get the current theme
38        this.currentTheme = jQuery('html')[0].dataset.theme;
39
40        // Set the theme switcher element and object
41        this.$themeSwitcherObject = jQuery(this.themeSwitcherSelector);
42
43        // Check if $themeSwitcherObject is a valid jQuery object
44        if (this.$themeSwitcherObject.length) {
45            // Set up event handlers
46            this.$themeSwitcherObject.on('click', this.switcherClickEvent.bind(this));
47            // Set up language switcher
48            this.maintainThemeOnLangSwitch();
49            // Set twitter theme on initialization
50            jQuery(this.twitterSelector).attr('data-theme', this.currentTheme);
51        }
52    },
53
54    init: function() {
55        document.addEventListener('DOMContentLoaded', function() {
56            siteTheme.initializeSwitcher();
57        });
58    },
59
60    /**
61     * When the switcher is clicked, update the theme and Icon. If an amchart is present, reload the page
62     * @param {event}event Mousedown event when clicking on the switch theme
63     * @returns {void}
64     */
65    switcherClickEvent: function (event) {
66        event.preventDefault();
67
68        let newTheme = 'light';
69        // If it's currently light, then switch to dark
70        if (siteTheme.currentTheme === 'light') {
71            newTheme = 'dark';
72        }
73
74        // Reload the page if an AmChart is present on the page, otherwise switch on the page
75        if (siteTheme.hasAmchartOnPage()) {
76            // Set the theme mode to the new theme, then refresh by setting the window location
77            let url = new URL(window.location.toString());
78            url.searchParams.set('theme_mode', newTheme);
79            window.location.href = url.toString();
80        } else {
81            siteTheme.setTheme(newTheme);
82            siteTheme.switchTweetTheme();
83            siteTheme.maintainThemeOnLangSwitch();
84        }
85    },
86
87    /**
88     * Disable dark mode
89     * @returns {void}
90     */
91    disableDarkMode: function () {
92        jQuery(this.themeSwitcherSelector).remove();
93    },
94
95    /**
96     * Set the main html tag data-theme
97     * @param {string}theme The theme name to use
98     * @returns {void}
99     */
100    setTheme: function (theme) {
101        this.currentTheme = theme;
102        document.documentElement.setAttribute('data-theme', this.currentTheme);
103        localStorage.setItem('theme', this.currentTheme);
104    },
105
106    /**
107     * Set the theme by url parameter if the key exists
108     * @returns {string} The theme from url or empty string
109     */
110    getThemeFromUrl: function () {
111        let theme = '';
112        // This is assuming that the url is of the form ../../page/?key=value
113        let url = new URL(window.location.toString());
114        if (url.searchParams.has('theme_mode')) {
115            let themeMode = url.searchParams.get('theme_mode').toLowerCase();
116            let themes = ['dark', 'light'];
117            if (themes.includes(themeMode)) {
118                theme = themeMode;
119            }
120        }
121        return theme;
122    },
123
124    /**
125     * Set the theme dark if the user browser preference is dark mode
126     * @returns {string} The theme name by preference (if dark is their default)
127     */
128    getThemeByUserPref: function () {
129        let theme = '';
130        if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
131            theme = 'dark';
132        }
133        return theme;
134    },
135
136    /**
137     * Change theme of tweets
138     * @returns {void}
139     */
140    switchTweetTheme: function () {
141        let tweets = document.querySelectorAll('[data-tweet-id]');
142        tweets.forEach(function (tweet) {
143            let src = new URL(tweet.getAttribute("src"));
144            const tweetTheme = src.searchParams.get('theme');
145            if (tweetTheme !== siteTheme.currentTheme) {
146                src.searchParams.set('theme', siteTheme.currentTheme);
147                tweet.setAttribute("src", src.href);
148            }
149        });
150    },
151
152    /**
153     * Checks there are AmChart charts present
154     * @returns {boolean} True if AmChart charts are present, false otherwise
155     */
156    hasAmchartOnPage: function () {
157        let hasChart = false;
158        if (typeof AmCharts !== 'undefined' || typeof am4core !== 'undefined') {
159            hasChart = true;
160        }
161        return hasChart;
162    },
163
164    /**
165     * Maintains the users theme when switching languages
166     * @return {void}
167     */
168    maintainThemeOnLangSwitch: function () {
169        let langSwitch = jQuery('#langSwitch');
170        // If there's a language switcher present
171        if (langSwitch.length) {
172            // Get the url
173            let langSwitchLink = new URL(langSwitch.attr('href'));
174            // Add a theme mode
175            langSwitchLink.searchParams.set('theme_mode', this.currentTheme);
176            // Update the url
177            langSwitch.attr("href", langSwitchLink.href);
178            // If there's a mobile language switcher update that link as well.
179            let langSwitchMobile = jQuery('#langSwitch.navbar-toggle');
180            if (langSwitchMobile.length) {
181                langSwitchMobile.attr("href", langSwitchLink.href);
182            }
183        }
184    }
185};
186
187//if the browser supports multiple themes, and local storage is available set the page theme
188if (!window.navigator.userAgent.match(/Trident.*rv:11\./) && storageAvailable.checkLocalStorage()) {
189    // Get the different storages for themes
190    let themeFromUrl, themeFromStorage, themeFromUserPref;
191
192    // Set the current theme as the default
193    let themeToUse = siteTheme.currentTheme;
194    // Order of which storage to use for determining the theme. URL -> Storage -> User preference -> Default 'light'
195    if (siteTheme.availableThemes.includes(themeFromUrl = siteTheme.getThemeFromUrl())) {
196        themeToUse = themeFromUrl;
197    } else if (siteTheme.availableThemes.includes(themeFromStorage = localStorage.getItem('theme'))) {
198        themeToUse = themeFromStorage;
199    } else if (siteTheme.availableThemes.includes(themeFromUserPref = siteTheme.getThemeByUserPref())) {
200        themeToUse = themeFromUserPref;
201    }
202    siteTheme.setTheme(themeToUse);
203} else {
204    siteTheme.disableDarkMode();
205}
206
207siteTheme.init();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.