PluginProbe
Darkify – Dark Mode & Night Mode for Website & Admin (Dark Theme Included) / 1.5.2
Darkify – Dark Mode & Night Mode for Website & Admin (Dark Theme Included) v1.5.2
2.1.3 2.1.2 2.1.1 2.1.0 2.0.4 2.0.3 2.0.2 2.0.1 2.0.0 1.5.5 1.5.4 1.5.3 1.5.2 1.5.1 1.5.0 trunk 1.0.1 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 All 57 releases
darkify / src / assets / js / client_main.js

client_main.js in Darkify – Dark Mode & Night Mode for Website & Admin (Dark Theme Included) 1.5.2, at src/assets/js/client_main.js

1,372 lines 41.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 "use strict";
2
3 let has_process_run_at_least_once = false;
4 let old_transition = "";
5 let has_background_img_url = false;
6 let darken_level = parseInt(darkify_bg_image_darken_to) / 100;
7 darken_level = darken_level.toFixed(1);
8 let darkify_secondary_bg_color = "";
9
10 darkify_init_keyboard_shortcut_listener();
11 darkify_init_os_mode_change_listener();
12
13 const darkify_observer = new MutationObserver(function (mutationsList) {
14 darkify_init_processes();
15
16 darkify_process_iframes(); // �
17 darkify proceed iframe
18 });
19
20 const elements_class_changed = new MutationObserver((mutationsList) => {
21 if (document.readyState !== "loading") {
22 mutationsList.forEach((mutation) => {
23 const target = mutation.target;
24
25 if (target.classList.contains("darkify_processed")) {
26 if (!target.hasAttribute("data-darkify_preserved_classes")) {
27 target.dataset.darkify_preserved_classes =
28 target.classList.toString();
29 } else {
30 if (
31 target.dataset.darkify_preserved_classes ===
32 target.classList.toString()
33 ) {
34 return;
35 }
36 }
37
38 target.dataset.darkify_preserved_classes = target.classList.toString();
39 elements_class_changed.disconnect();
40 target.classList.remove("darkify_processed");
41 darkify_process_element(target);
42
43 document
44 .querySelectorAll(
45 "*:not(head, title, link, meta, script, style, defs, filter)",
46 )
47 .forEach((element) => {
48 elements_class_changed.observe(element, {
49 attributes: true,
50 attributeFilter: ["class"],
51 });
52 });
53 }
54 });
55 }
56 });
57
58 const dark_mode_status_changed = new MutationObserver((mutationsList) => {
59 mutationsList.forEach((mutation) => {
60 if (mutation.type === "attributes" && mutation.attributeName === "class") {
61 document
62 .querySelectorAll(
63 "*:not(head, title, link, meta, script, style, defs, filter)",
64 )
65 .forEach((element) => {
66 if (element.classList.contains("darkify_processed")) {
67 if (
68 darkify_disallowed_elements.length > 0 &&
69 element.matches(darkify_disallowed_elements)
70 ) {
71 return;
72 }
73 if (darkify_enable_bg_image_darken === "1") {
74 darkify_darken_bg_image(element, darken_level);
75 }
76 if (
77 (darkify_enable_low_image_brightness === "1" ||
78 darkify_enable_image_grayscale === "1") &&
79 element.nodeName.toLowerCase() === "img"
80 ) {
81 darkify_img_brightness_and_grayscale(element);
82 }
83 if (
84 darkify_enable_invert_inline_svg === "1" &&
85 element.nodeName.toLowerCase() === "svg"
86 ) {
87 darkify_invert_inline_svg(element);
88 }
89 if (
90 darkify_enable_low_video_brightness === "1" ||
91 darkify_enable_video_grayscale === "1"
92 ) {
93 if (element.nodeName.toLowerCase() === "video") {
94 darkify_video_brightness_and_grayscale(element);
95 }
96 if (
97 element.nodeName.toLowerCase() === "iframe" &&
98 element.getAttribute("src") != null
99 ) {
100 const srcAttribute = element.getAttribute("src");
101 if (
102 srcAttribute.includes("youtube") ||
103 srcAttribute.includes("vimeo") ||
104 srcAttribute.includes("dailymotion")
105 ) {
106 darkify_video_brightness_and_grayscale(element);
107 }
108 }
109 }
110 if (element.hasAttribute("data-darkify_alpha_bg")) {
111 darkify_fix_background_color_alpha(element);
112 }
113 }
114 });
115 }
116 });
117 });
118
119 function darkify_change_state() {
120 if (darkify_is_this_admin_panel === "1") {
121 localStorage.darkify_admin_panel_last_state = document
122 .getElementsByTagName("html")[0]
123 .classList.contains("darkify_dark_mode_enabled")
124 ? "1"
125 : "0";
126 } else {
127 localStorage.darkify_last_state = document
128 .getElementsByTagName("html")[0]
129 .classList.contains("darkify_dark_mode_enabled")
130 ? "1"
131 : "0";
132 }
133 }
134
135 function darkify_switch_trigger() {
136 if (!has_process_run_at_least_once) {
137 darkify_init_processes();
138 darkify_init_observer();
139 }
140
141 const htmlElement = document.getElementsByTagName("html")[0];
142
143 if (htmlElement.classList.contains("darkify_dark_mode_enabled")) {
144 htmlElement.classList.remove("darkify_dark_mode_enabled");
145 } else {
146 htmlElement.classList.add("darkify_dark_mode_enabled");
147 }
148
149 darkify_change_state();
150
151 darkify_process_iframes(); // �
152 darkify proceed iframe
153 }
154 function darkify_theme_select(theme) {
155 if (!darkify_is_block_editor_context()) return;
156 if (!has_process_run_at_least_once) {
157 darkify_init_processes();
158 darkify_init_observer();
159 }
160
161 const htmlElement = document.documentElement;
162
163 // �
164 Remove all previous theme classes (IMPORTANT)
165 htmlElement.classList.forEach((cls) => {
166 if (cls.startsWith("darkify-")) {
167 htmlElement.classList.remove(cls);
168 }
169 });
170
171 // �
172 Save in localStorage
173 localStorage.darkify_selected_theme = theme;
174
175 // �
176 Update all select dropdowns
177 darkify_update_theme_selectors(theme);
178
179 if (darkify_is_this_admin_panel === "1") {
180 if (localStorage.darkify_admin_panel_last_state === "1") {
181 htmlElement.classList.add("darkify_dark_mode_enabled");
182 htmlElement.classList.add("darkify-" + theme);
183 } else {
184 htmlElement.classList.remove("darkify_dark_mode_enabled");
185 }
186 }
187
188 darkify_change_state();
189
190 darkify_process_iframes();
191
192 darkify_apply_palette(theme);
193 }
194
195 document.addEventListener("DOMContentLoaded", function () {
196 if (!darkify_is_block_editor_context()) return;
197
198 let theme = localStorage.getItem("darkify_selected_theme") || "set1";
199
200 darkify_theme_select(theme);
201 });
202
203 function darkify_update_theme_selectors(theme) {
204 document
205 .querySelectorAll(".darkify-theme-selector")
206 .forEach(function (select) {
207 if (select.value !== theme) {
208 select.value = theme;
209 }
210 });
211 }
212
213 function darkify_is_block_editor_context() {
214 return (
215 typeof document !== "undefined" &&
216 document.body &&
217 (document.body.classList.contains("block-editor-page") ||
218 document.querySelector(".edit-post-visual-editor") !== null ||
219 document.querySelector(".block-editor") !== null)
220 );
221 }
222
223 function darkify_restore_selected_theme() {
224 if (!darkify_is_block_editor_context()) return;
225 const storedTheme = localStorage.darkify_selected_theme;
226
227 if (!storedTheme) return;
228
229 darkify_update_theme_selectors(storedTheme);
230 darkify_theme_select(storedTheme);
231 }
232
233 function darkify_apply_palette(theme) {
234 if (!darkify_is_block_editor_context()) return;
235 const palettes = {
236 set1: {
237 bg: "#0F0F0F",
238 secondary_bg: "#171717",
239 text_color: "#BEBEBE",
240 link_color: "#E7E7E7",
241 link_hover_color: "#BEBEBE",
242 input_bg: "#2D2D2D",
243 input_text_color: "#BEBEBE",
244 input_placeholder_color: "#BEBEBE",
245 border_color: "#4A4A4A",
246 btn_text_color: "#BEBEBE",
247 btn_bg: "#4A4A4A",
248 btn_text_hover_color: "#BEBEBE",
249 btn_hover_bg: "#2D2D2D",
250 },
251 set3: {
252 bg: "#211e3c",
253 secondary_bg: "#302C57",
254 text_color: "#B1BBD8",
255 link_color: "#8071fb",
256 link_hover_color: "#B1BBD8",
257 input_bg: "#2A264D",
258 input_text_color: "#B1BBD8",
259 input_placeholder_color: "#B1BBD8",
260 border_color: "#4E478D",
261 btn_text_color: "#B1BBD8",
262 btn_bg: "#4E478D",
263 btn_text_hover_color: "#B1BBD8",
264 btn_hover_bg: "#2A264D",
265 },
266
267 set6: {
268 bg: "#082032",
269 secondary_bg: "#061825",
270 text_color: "#B5D9F3",
271 link_color: "#61bbff",
272 link_hover_color: "#B5D9F3",
273 input_bg: "#0E3755",
274 input_text_color: "#B5D9F3",
275 input_placeholder_color: "#B5D9F3",
276 border_color: "#144E78",
277 btn_text_color: "#B5D9F3",
278 btn_bg: "#144E78",
279 btn_text_hover_color: "#B5D9F3",
280 btn_hover_bg: "#0E3755",
281 },
282
283 set9: {
284 bg: "#04261d",
285 secondary_bg: "#021e16",
286 text_color: "#C1D2BB",
287 link_color: "#00d29a",
288 link_hover_color: "#C1D2BB",
289 input_bg: "#073d2f",
290 input_text_color: "#C1D2BB",
291 input_placeholder_color: "#C1D2BB",
292 border_color: "#095541",
293 btn_text_color: "#C1D2BB",
294 btn_bg: "#095541",
295 btn_text_hover_color: "#C1D2BB",
296 btn_hover_bg: "#073d2f",
297 },
298
299 set10: {
300 bg: "#171004",
301 secondary_bg: "#211706",
302 text_color: "#E0D2BD",
303 link_color: "#e09525",
304 link_hover_color: "#E0D2BD",
305 input_bg: "#372911",
306 input_text_color: "#E0D2BD",
307 input_placeholder_color: "#E0D2BD",
308 border_color: "#5D4010",
309 btn_text_color: "#E0D2BD",
310 btn_bg: "#5D4010",
311 btn_text_hover_color: "#E0D2BD",
312 btn_hover_bg: "#372911",
313 },
314 };
315
316 const palette = palettes[theme] || palettes["default"];
317
318 document.documentElement.style.setProperty(
319 "--darkify_dark_mode_bg",
320 palette.bg,
321 );
322 document.documentElement.style.setProperty(
323 "--darkify_dark_mode_secondary_bg",
324 palette.secondary_bg,
325 );
326 document.documentElement.style.setProperty(
327 "--darkify_dark_mode_text_color",
328 palette.text_color,
329 );
330 document.documentElement.style.setProperty(
331 "--darkify_dark_mode_link_color",
332 palette.link_color,
333 );
334 document.documentElement.style.setProperty(
335 "--darkify_dark_mode_link_hover_color",
336 palette.link_hover_color,
337 );
338 document.documentElement.style.setProperty(
339 "--darkify_dark_mode_input_bg",
340 palette.input_bg,
341 );
342 document.documentElement.style.setProperty(
343 "--darkify_dark_mode_input_text_color",
344 palette.input_text_color,
345 );
346 document.documentElement.style.setProperty(
347 "--darkify_dark_mode_input_placeholder_color",
348 palette.input_placeholder_color,
349 );
350 document.documentElement.style.setProperty(
351 "--darkify_dark_mode_border_color",
352 palette.border_color,
353 );
354 document.documentElement.style.setProperty(
355 "--darkify_dark_mode_btn_bg",
356 palette.btn_bg,
357 );
358 document.documentElement.style.setProperty(
359 "--darkify_dark_mode_btn_text_color",
360 palette.btn_text_color,
361 );
362 document.documentElement.style.setProperty(
363 "--darkify_dark_mode_btn_hover_bg",
364 palette.btn_hover_bg,
365 );
366 document.documentElement.style.setProperty(
367 "--darkify_dark_mode_btn_text_hover_color",
368 palette.btn_text_hover_color,
369 );
370 }
371
372 // Iframe dark mode implementation functions
373 function darkify_copy_root_vars_to_iframe(iframeDoc) {
374 const parentStyle = document.querySelector("style.darkify_inline_css");
375 if (!parentStyle) return;
376
377 let style = iframeDoc.getElementById("darkify-iframe-vars");
378 if (!style) {
379 style = iframeDoc.createElement("style");
380 style.id = "darkify-iframe-vars";
381 iframeDoc.head.appendChild(style);
382 }
383
384 // Copy the whole :root { ... } block as-is
385 style.textContent = parentStyle.textContent;
386 }
387
388 function darkify_inject_css_into_iframe(iframeDoc) {
389 if (iframeDoc.getElementById("darkify-iframe-css")) return;
390
391 const style = iframeDoc.createElement("style");
392 style.id = "darkify-iframe-css";
393 style.textContent = `
394 html.darkify_dark_mode_enabled,
395 html.darkify_dark_mode_enabled body {
396 background: var(--darkify_dark_mode_secondary_bg) !important;
397 color: var(--darkify_dark_mode_text_color) !important;
398 }
399
400 html.darkify_dark_mode_enabled a {
401 color: var(--darkify_dark_mode_link_color) !important;
402 }
403 html.darkify_dark_mode_enabled a:hover {
404 color: var(--darkify_dark_mode_link_hover_color) !important;
405 }
406
407 html.darkify_dark_mode_enabled input,
408 html.darkify_dark_mode_enabled select,
409 html.darkify_dark_mode_enabled textarea {
410 background: var(--darkify_dark_mode_input_bg) !important;
411 color: var(--darkify_dark_mode_input_text_color) !important;
412 border-color: var(--darkify_dark_mode_border_color) !important;
413 }
414
415 html.darkify_dark_mode_enabled input::placeholder,
416 html.darkify_dark_mode_enabled textarea::placeholder {
417 color: var(--darkify_dark_mode_input_placeholder_color) !important;
418 }
419
420 /* TinyMCE editor body */
421 html.darkify_dark_mode_enabled body#tinymce,
422 html.darkify_dark_mode_enabled .mce-content-body {
423 background: var(--darkify_dark_mode_secondary_bg) !important;
424 color: var(--darkify_dark_mode_text_color) !important;
425 }
426 `;
427 iframeDoc.head.appendChild(style);
428 }
429
430 function darkify_apply_dark_to_iframe(iframe) {
431 if (darkify_is_this_admin_panel === "1") return;
432 try {
433 const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;
434 if (!iframeDoc || !iframeDoc.documentElement) return;
435
436 const enabled = document.documentElement.classList.contains(
437 "darkify_dark_mode_enabled",
438 );
439
440 if (enabled) {
441 iframeDoc.documentElement.classList.add("darkify_dark_mode_enabled");
442
443 // �
444 copy vars first, then inject CSS that uses them
445 darkify_copy_root_vars_to_iframe(iframeDoc);
446 darkify_inject_css_into_iframe(iframeDoc);
447 } else {
448 iframeDoc.documentElement.classList.remove("darkify_dark_mode_enabled");
449 }
450 } catch (e) {
451 // cross-origin -> can't access
452 }
453 }
454
455 function darkify_process_iframes() {
456 // 🚫 If admin panel, stop immediately
457 if (darkify_is_this_admin_panel === "1") {
458 return;
459 }
460
461 document.querySelectorAll("iframe").forEach(darkify_apply_dark_to_iframe);
462 }
463
464 function darkify_init_keyboard_shortcut_listener() {
465 if (darkify_enable_keyboard_shortcut === "1") {
466 document.onkeydown = function (event) {
467 if (event.ctrlKey && event.altKey && event.keyCode === 0x44) {
468 darkify_switch_trigger();
469 }
470 };
471 }
472 }
473
474 function darkify_init_os_mode_change_listener() {
475 if (darkify_is_this_admin_panel === "0" && darkify_enable_os_aware === "1") {
476 window
477 .matchMedia("(prefers-color-scheme: dark)")
478 .addEventListener("change", (event) => {
479 const mode = event.matches ? "dark" : "light";
480 const htmlElement = document.getElementsByTagName("html")[0];
481 if (mode === "dark") {
482 htmlElement.classList.add("darkify_dark_mode_enabled");
483 } else if (mode === "light") {
484 htmlElement.classList.remove("darkify_dark_mode_enabled");
485 }
486
487 darkify_change_state();
488 });
489 }
490 }
491
492 function darkify_init_alternative_dark_mode_switch() {
493 if (darkify_alternative_dark_mode_switch.length > 0) {
494 const elements = document.querySelectorAll(
495 darkify_alternative_dark_mode_switch,
496 );
497 for (let i = 0; i < elements.length; i++) {
498 const element = elements[i];
499 element.addEventListener("click", () => {
500 darkify_switch_trigger();
501 });
502 }
503 }
504 }
505
506 function get_bg_color_to_preserve(element, fromDataset) {
507 let color = window.getComputedStyle(element, null).backgroundColor;
508 if (!fromDataset) {
509 color = element.dataset.darkify_preserved_bg;
510 }
511 if (
512 (color === "transparent" ||
513 color === "rgba(0, 0, 0, 0)" ||
514 color === "rgba(255,255,255,0)") &&
515 element.parentNode.nodeType === 1
516 ) {
517 color = get_bg_color_to_preserve(element.parentNode, false);
518 } else if (
519 element.parentNode.nodeType === 1 &&
520 element.parentNode.hasAttribute("data-darkify_preserved_bg") &&
521 window.getComputedStyle(element.parentNode, null).backgroundColor === color
522 ) {
523 color = get_bg_color_to_preserve(element.parentNode, false);
524 }
525 return color;
526 }
527
528 function get_txt_color_to_preserve(element, fromDataset) {
529 let color = window.getComputedStyle(element, null).color;
530 if (!fromDataset) {
531 color = element.dataset.darkify_preserved_color;
532 }
533 if (
534 (color === "transparent" ||
535 color === "rgba(0, 0, 0, 0)" ||
536 color === "rgba(255,255,255,0)") &&
537 element.parentNode.nodeType === 1
538 ) {
539 color = get_txt_color_to_preserve(element.parentNode, false);
540 } else if (
541 element.parentNode.nodeType === 1 &&
542 element.parentNode.hasAttribute("data-darkify_preserved_color") &&
543 window.getComputedStyle(element.parentNode, null).color === color
544 ) {
545 color = get_txt_color_to_preserve(element.parentNode, false);
546 }
547 return color;
548 }
549
550 function darkify_darken_bg_image(element, level) {
551 if (
552 document
553 .getElementsByTagName("html")[0]
554 .classList.contains("darkify_dark_mode_enabled")
555 ) {
556 const mainStyle = window.getComputedStyle(element, null);
557 const beforeStyle = window.getComputedStyle(element, ":before");
558 const afterStyle = window.getComputedStyle(element, ":after");
559
560 if (
561 mainStyle.backgroundImage !== "none" &&
562 mainStyle.backgroundImage.includes("url") &&
563 !mainStyle.backgroundImage.includes("rgba(0, 0, 0, " + level + ")")
564 ) {
565 element.style.setProperty(
566 "background-image",
567 "linear-gradient(rgba(0, 0, 0, " +
568 level +
569 "), rgba(0, 0, 0, " +
570 level +
571 ")), " +
572 mainStyle.backgroundImage,
573 );
574 }
575
576 // Process :before pseudo-element
577 if (
578 beforeStyle.backgroundImage !== "none" &&
579 beforeStyle.backgroundImage.includes("url") &&
580 !beforeStyle.backgroundImage.includes("rgba(0, 0, 0, " + level + ")")
581 ) {
582 // Create a style element for this specific element
583 const styleId = `darkify-before-${Math.random()
584 .toString(36)
585 .substr(2, 9)}`;
586 element.setAttribute("data-darkify-style-id", styleId);
587
588 let styleElement = document.getElementById(styleId);
589 if (!styleElement) {
590 styleElement = document.createElement("style");
591 styleElement.id = styleId;
592 document.head.appendChild(styleElement);
593 }
594
595 // Store original background for reset
596 element.dataset.darkifyOriginalBeforeBg = beforeStyle.backgroundImage;
597
598 // Add the styles for :before
599 const cssText = `
600 .darkify_dark_mode_enabled [data-darkify-style-id="${styleId}"]::before {
601 background-image: linear-gradient(rgba(0, 0, 0, ${level}), rgba(0, 0, 0, ${level})), ${beforeStyle.backgroundImage} !important;
602 }
603 `;
604 styleElement.textContent = cssText;
605
606 // Ensure position relative on parent
607 if (window.getComputedStyle(element).position === "static") {
608 element.style.position = "relative";
609 }
610 }
611 // Process :after pseudo-element
612 if (
613 afterStyle.backgroundImage !== "none" &&
614 afterStyle.backgroundImage.includes("url") &&
615 !afterStyle.backgroundImage.includes("rgba(0, 0, 0, " + level + ")")
616 ) {
617 // Create a style element for this specific element
618 const styleId = `darkify-after-${Math.random()
619 .toString(36)
620 .substr(2, 9)}`;
621 element.setAttribute("data-darkify-style-id", styleId);
622
623 let styleElement = document.getElementById(styleId);
624 if (!styleElement) {
625 styleElement = document.createElement("style");
626 styleElement.id = styleId;
627 document.head.appendChild(styleElement);
628 }
629
630 // Store original background for reset
631 element.dataset.darkifyOriginalAfterBg = afterStyle.backgroundImage;
632
633 // Add the styles for :after
634 const cssText = `
635 .darkify_dark_mode_enabled [data-darkify-style-id="${styleId}"]::after {
636 background-image: linear-gradient(rgba(0, 0, 0, ${level}), rgba(0, 0, 0, ${level})), ${afterStyle.backgroundImage} !important;
637 }
638 `;
639 styleElement.textContent = cssText;
640
641 // Ensure position relative on parent
642 if (window.getComputedStyle(element).position === "static") {
643 element.style.position = "relative";
644 }
645 }
646 } else if (
647 window.getComputedStyle(element, null).backgroundImage !== "none" &&
648 window
649 .getComputedStyle(element, null)
650 .backgroundImage.includes("rgba(0, 0, 0, " + level + ")")
651 ) {
652 element.style.setProperty(
653 "background-image",
654 window
655 .getComputedStyle(element, null)
656 .backgroundImage.replace(
657 "linear-gradient(rgba(0, 0, 0, " +
658 level +
659 "), rgba(0, 0, 0, " +
660 level +
661 ")), ",
662 "",
663 ),
664 );
665 }
666 }
667
668 function darkify_img_brightness_and_grayscale(element) {
669 if (
670 document
671 .getElementsByTagName("html")[0]
672 .classList.contains("darkify_dark_mode_enabled")
673 ) {
674 if (
675 !element.classList.contains("darkify_changed_brightness_and_grayscale")
676 ) {
677 element.dataset.darkify_preserved_filter = element.style.filter;
678 element.classList.add("darkify_changed_brightness_and_grayscale");
679
680 if (
681 darkify_enable_low_image_brightness === "1" &&
682 darkify_enable_image_grayscale === "1"
683 ) {
684 element.style.filter =
685 "brightness(" +
686 darkify_image_brightness_to +
687 "%)" +
688 " " +
689 "grayscale(" +
690 darkify_image_grayscale_to +
691 "%)";
692 } else {
693 if (darkify_enable_low_image_brightness === "1") {
694 element.style.filter =
695 "brightness(" + darkify_image_brightness_to + "%)";
696 } else if (darkify_enable_image_grayscale === "1") {
697 element.style.filter =
698 "grayscale(" + darkify_image_grayscale_to + "%)";
699 }
700 }
701 }
702 } else if (
703 element.classList.contains("darkify_changed_brightness_and_grayscale")
704 ) {
705 element.style.filter = element.dataset.darkify_preserved_filter;
706 element.classList.remove("darkify_changed_brightness_and_grayscale");
707 delete element.dataset.darkify_preserved_filter;
708 }
709 }
710
711 function darkify_invert_inline_svg(element) {
712 if (document.body.classList.contains("block-editor-page")) return;
713 if (
714 document
715 .getElementsByTagName("html")[0]
716 .classList.contains("darkify_dark_mode_enabled")
717 ) {
718 element.style.filter = "invert(1)";
719 element.classList.add("darkify_inverted_inline_svg");
720 } else if (element.classList.contains("darkify_inverted_inline_svg")) {
721 element.style.filter = element.style.filter.replace("invert(1)", "");
722 element.classList.remove("darkify_inverted_inline_svg");
723 }
724 }
725
726 function darkify_video_brightness_and_grayscale(element) {
727 if (
728 document
729 .getElementsByTagName("html")[0]
730 .classList.contains("darkify_dark_mode_enabled")
731 ) {
732 if (
733 !element.classList.contains(
734 "darkify_changed_video_brightness_and_grayscale",
735 )
736 ) {
737 element.dataset.darkify_preserved_filter = element.style.filter;
738 element.classList.add("darkify_changed_video_brightness_and_grayscale");
739 if (
740 darkify_enable_low_video_brightness === "1" &&
741 darkify_enable_video_grayscale === "1"
742 ) {
743 element.style.filter =
744 "brightness(" +
745 darkify_video_brightness_to +
746 "%)" +
747 " " +
748 "grayscale(" +
749 darkify_video_grayscale_to +
750 "%)";
751 } else {
752 if (darkify_enable_low_video_brightness === "1") {
753 element.style.filter =
754 "brightness(" + darkify_video_brightness_to + "%)";
755 } else if (darkify_enable_video_grayscale === "1") {
756 element.style.filter =
757 "grayscale(" + darkify_video_grayscale_to + "%)";
758 }
759 }
760 }
761 } else if (
762 element.classList.contains("darkify_changed_video_brightness_and_grayscale")
763 ) {
764 element.style.filter = element.dataset.darkify_preserved_filter;
765 element.classList.remove("darkify_changed_video_brightness_and_grayscale");
766 delete element.dataset.darkify_preserved_filter;
767 }
768 }
769
770 function darkify_replace_video(videoElement, videos) {
771 if (
772 document
773 .getElementsByTagName("html")[0]
774 .classList.contains("darkify_dark_mode_enabled")
775 ) {
776 for (let i = 0; i < videos.length; i++) {
777 const normalVideo = videos[i].normal_video;
778 const normalVideoPath = new URL(normalVideo).pathname;
779 const darkVideo = videos[i].dark_video;
780 const darkVideoPath = new URL(darkVideo).pathname;
781
782 if (
783 videoElement.getAttribute("src") != null &&
784 videoElement.getAttribute("src").includes(normalVideoPath)
785 ) {
786 videoElement.src = darkVideo;
787 videoElement.classList.add("darkify_replaced_video");
788 }
789
790 if (videoElement.querySelectorAll("source") != null) {
791 let sources = videoElement.querySelectorAll("source");
792 for (let j = 0; j < sources.length; j++) {
793 if (
794 sources[j].getAttribute("src") != null &&
795 sources[j].getAttribute("src").includes(normalVideoPath)
796 ) {
797 sources[j].src = darkVideo + "?_=" + Date.now();
798 videoElement.classList.add("darkify_replaced_video");
799 videoElement.load();
800 }
801 }
802 }
803 }
804 } else {
805 if (videoElement.classList.contains("darkify_replaced_video")) {
806 for (let i = 0; i < videos.length; i++) {
807 const normalVideo = videos[i].normal_video;
808 const normalVideoPath = new URL(normalVideo).pathname;
809 const darkVideo = videos[i].dark_video;
810 const darkVideoPath = new URL(darkVideo).pathname;
811
812 if (
813 videoElement.getAttribute("src") != null &&
814 videoElement.getAttribute("src").includes(darkVideoPath)
815 ) {
816 videoElement.src = normalVideo;
817 videoElement.classList.remove("darkify_replaced_video");
818 }
819
820 if (videoElement.querySelectorAll("source") != null) {
821 let sources = videoElement.querySelectorAll("source");
822 for (let j = 0; j < sources.length; j++) {
823 if (
824 sources[j].getAttribute("src") != null &&
825 sources[j].getAttribute("src").includes(darkVideoPath)
826 ) {
827 sources[j].src = normalVideo + "?_=" + Date.now();
828 videoElement.classList.remove("darkify_replaced_video");
829 videoElement.load();
830 }
831 }
832 }
833 }
834 }
835 }
836 }
837
838 function darkify_process_pseudo_bg(element) {
839 const isTransparent = (color) =>
840 !color ||
841 color === "transparent" ||
842 color === "rgba(0, 0, 0, 0)" ||
843 color === "rgba(255, 255, 255, 0)";
844
845 const beforeBg = window.getComputedStyle(element, "::before").backgroundColor;
846 const afterBg = window.getComputedStyle(element, "::after").backgroundColor;
847
848 if (!isTransparent(beforeBg)) {
849 element.setAttribute("data-darkify-pseudo-before-bg", beforeBg);
850 }
851 if (!isTransparent(afterBg)) {
852 element.setAttribute("data-darkify-pseudo-after-bg", afterBg);
853 }
854 }
855
856 function darkify_apply_pseudo_bg_styles() {
857 document
858 .querySelectorAll(
859 "[data-darkify-pseudo-before-bg], [data-darkify-pseudo-after-bg]",
860 )
861 .forEach((element) => {
862 const hasBefore = element.hasAttribute("data-darkify-pseudo-before-bg");
863 const hasAfter = element.hasAttribute("data-darkify-pseudo-after-bg");
864
865 let pseudoId = element.getAttribute("data-darkify-pseudo-bg-id");
866 if (!pseudoId) {
867 pseudoId = "dkf-" + Math.random().toString(36).substr(2, 9);
868 element.setAttribute("data-darkify-pseudo-bg-id", pseudoId);
869 }
870
871 let styleEl = document.getElementById("darkify-pseudo-bg-" + pseudoId);
872 if (!styleEl) {
873 styleEl = document.createElement("style");
874 styleEl.id = "darkify-pseudo-bg-" + pseudoId;
875 document.head.appendChild(styleEl);
876 }
877
878 let css = "";
879
880 if (hasBefore) {
881 const beforeBg = element.getAttribute("data-darkify-pseudo-before-bg");
882 const isSecondary =
883 darkify_secondary_bg_color !== "" &&
884 beforeBg !== darkify_secondary_bg_color;
885 const bgVar = isSecondary
886 ? "--darkify_dark_mode_secondary_bg"
887 : "--darkify_dark_mode_bg";
888 css += `
889 .darkify_dark_mode_enabled [data-darkify-pseudo-bg-id="${pseudoId}"]::before {
890 background: var(${bgVar}) !important;
891 background-color: var(${bgVar}) !important;
892 }
893 `;
894 }
895
896 if (hasAfter) {
897 const afterBg = element.getAttribute("data-darkify-pseudo-after-bg");
898 const isSecondary =
899 darkify_secondary_bg_color !== "" &&
900 afterBg !== darkify_secondary_bg_color;
901 const bgVar = isSecondary
902 ? "--darkify_dark_mode_secondary_bg"
903 : "--darkify_dark_mode_bg";
904 css += `
905 .darkify_dark_mode_enabled [data-darkify-pseudo-bg-id="${pseudoId}"]::after {
906 background: var(${bgVar}) !important;
907 background-color: var(${bgVar}) !important;
908 }
909 `;
910 }
911
912 styleEl.textContent = css;
913 });
914 }
915
916 function darkify_fix_background_color_alpha(element) {
917 if (
918 document
919 .getElementsByTagName("html")[0]
920 .classList.contains("darkify_dark_mode_enabled")
921 ) {
922 if (element.hasAttribute("data-darkify_alpha_bg")) {
923 var alphaValue = element.dataset.darkify_alpha_bg
924 .replace("rgba(", "")
925 .replace(")", "")
926 .split(",")[3]
927 .trim();
928 var backgroundColor = window.getComputedStyle(
929 element,
930 null,
931 ).backgroundColor;
932
933 if (!backgroundColor.includes("rgba")) {
934 element.style.setProperty(
935 "background-color",
936 backgroundColor
937 .replace(")", ", " + alphaValue + ")")
938 .replace("rgb", "rgba"),
939 "important",
940 );
941 }
942 }
943 } else if (element.hasAttribute("data-darkify_alpha_bg")) {
944 element.style.backgroundColor = "";
945 }
946 }
947
948 function darkify_implement_secondary_bg() {
949 let maxAreaElement = null;
950 let maxArea = 0;
951
952 const elements = document.querySelectorAll(
953 "* :not(head, title, link, meta, script, style, defs, filter)",
954 );
955
956 for (let i = 0; i < elements.length; i++) {
957 const element = elements[i];
958 if (element.hasAttribute("data-darkify_secondary_bg_finder")) {
959 const secondaryBgColor = element.dataset.darkify_secondary_bg_finder;
960 if (
961 secondaryBgColor !== "transparent" &&
962 secondaryBgColor !== "rgba(0, 0, 0, 0)"
963 ) {
964 const boundingRect = element.getBoundingClientRect();
965 const area = boundingRect.width * boundingRect.height;
966 if (area > maxArea) {
967 maxArea = area;
968 maxAreaElement = secondaryBgColor;
969 }
970 }
971 }
972 }
973
974 for (let i = 0; i < elements.length; i++) {
975 const element = elements[i];
976 if (element.hasAttribute("data-darkify_secondary_bg_finder")) {
977 if (
978 element.classList.contains("darkify_style_all") ||
979 element.classList.contains("darkify_style_bg_txt") ||
980 element.classList.contains("darkify_style_bg_border") ||
981 element.classList.contains("darkify_style_bg")
982 ) {
983 const isDifferentSecondaryBg =
984 maxAreaElement !== element.dataset.darkify_secondary_bg_finder;
985 if (isDifferentSecondaryBg) {
986 element.classList.add("darkify_style_secondary_bg");
987 }
988 }
989 delete element.dataset.darkify_secondary_bg_finder;
990 }
991 }
992
993 darkify_secondary_bg_color = maxAreaElement;
994 }
995
996 function darkify_recheck_on_css_loaded_later() {
997 document
998 .querySelectorAll(
999 ".darkify_style_txt_border, .darkify_style_txt, .darkify_style_border",
1000 )
1001 .forEach(function (element) {
1002 const computedStyle = window.getComputedStyle(element, null);
1003 const backgroundColor = computedStyle.backgroundColor;
1004 if (
1005 backgroundColor !== "rgba(0, 0, 0, 0)" &&
1006 backgroundColor !== "rgba(255, 255, 255, 0)"
1007 ) {
1008 darkify_process_element(element);
1009 }
1010 });
1011 }
1012
1013 function darkify_check_preloading() {
1014 let isPreloaded = false;
1015 const lastState = localStorage.darkify_last_state
1016 ? localStorage.darkify_last_state
1017 : "not_set";
1018 const adminPanelLastState = localStorage.darkify_admin_panel_last_state
1019 ? localStorage.darkify_admin_panel_last_state
1020 : "not_set";
1021
1022 if (darkify_is_this_admin_panel === "1") {
1023 if (adminPanelLastState === "1") {
1024 isPreloaded = true;
1025 }
1026 } else {
1027 if (lastState === "1" || lastState === "0") {
1028 if (lastState === "1") {
1029 isPreloaded = true;
1030 }
1031 } else {
1032 if (darkify_enable_default_dark_mode === "1") {
1033 isPreloaded = true;
1034 }
1035 if (darkify_enable_time_based_dark === "1") {
1036 const currentDate = new Date();
1037 const darkStart = new Date();
1038 const darkStop = new Date();
1039 darkStart.setHours(
1040 parseInt(darkify_time_based_dark_start.split(":")[0]),
1041 );
1042 darkStart.setMinutes(
1043 parseInt(darkify_time_based_dark_start.split(":")[1]),
1044 );
1045 darkStop.setHours(parseInt(darkify_time_based_dark_stop.split(":")[0]));
1046 darkStop.setMinutes(
1047 parseInt(darkify_time_based_dark_stop.split(":")[1]),
1048 );
1049
1050 if (
1051 parseInt(darkify_time_based_dark_stop.split(":")[0]) >=
1052 parseInt(darkify_time_based_dark_start.split(":")[0])
1053 ) {
1054 if (
1055 currentDate.getTime() > darkStart.getTime() &&
1056 currentDate.getTime() < darkStop.getTime()
1057 ) {
1058 isPreloaded = true;
1059 }
1060 } else if (currentDate.getHours() > 12) {
1061 if (
1062 currentDate.getTime() > darkStart.getTime() &&
1063 currentDate.getTime() > darkStop.getTime()
1064 ) {
1065 isPreloaded = true;
1066 }
1067 } else if (
1068 currentDate.getTime() < darkStart.getTime() &&
1069 currentDate.getTime() < darkStop.getTime()
1070 ) {
1071 isPreloaded = true;
1072 }
1073 }
1074 }
1075 }
1076
1077 if (
1078 darkify_is_this_admin_panel === "0" &&
1079 darkify_enable_os_aware === "1" &&
1080 window.matchMedia &&
1081 window.matchMedia("(prefers-color-scheme: dark)").matches &&
1082 lastState !== "1" &&
1083 lastState !== "0"
1084 ) {
1085 isPreloaded = true;
1086 }
1087
1088 return isPreloaded;
1089 }
1090
1091 function darkify_process_element(element) {
1092 var computedStyle = window.getComputedStyle(element, null);
1093 var old_transition = "";
1094
1095 // if (computedStyle.transition !== "all 0s ease 0s") {
1096 // old_transition = computedStyle.transition;
1097 // // element.style.setProperty("transition", "none");
1098 // }
1099
1100 if (
1101 element.classList.contains("darkify_style_all") ||
1102 element.classList.contains("darkify_style_bg_txt") ||
1103 element.classList.contains("darkify_style_bg_border") ||
1104 element.classList.contains("darkify_style_txt_border") ||
1105 element.classList.contains("darkify_style_bg") ||
1106 element.classList.contains("darkify_style_txt") ||
1107 element.classList.contains("darkify_style_border") ||
1108 element.classList.contains("darkify_style_secondary_bg")
1109 ) {
1110 element.classList.remove("darkify_style_all");
1111 element.classList.remove("darkify_style_bg_txt");
1112 element.classList.remove("darkify_style_bg_border");
1113 element.classList.remove("darkify_style_txt_border");
1114 element.classList.remove("darkify_style_bg");
1115 element.classList.remove("darkify_style_txt");
1116 element.classList.remove("darkify_style_border");
1117 element.classList.remove("darkify_style_secondary_bg");
1118 }
1119
1120 var nodeName = element.nodeName.toLowerCase();
1121 var backgroundColor = computedStyle.backgroundColor;
1122 var color = computedStyle.color;
1123 var borderColor = computedStyle.borderColor;
1124 var backgroundImage = computedStyle.backgroundImage;
1125
1126 if (
1127 nodeName === "body" &&
1128 (backgroundColor === "rgba(0, 0, 0, 0)" ||
1129 backgroundColor === "rgba(255, 255, 255, 0)")
1130 ) {
1131 element.style.setProperty("background-color", "rgb(255, 255, 255)");
1132 backgroundColor = window.getComputedStyle(element, null).backgroundColor;
1133 }
1134
1135 if (darkify_disallowed_elements.length > 0) {
1136 if (element.matches(darkify_disallowed_elements)) {
1137 // if (old_transition !== "") {
1138 // element.style.setProperty("transition", old_transition);
1139 // }
1140 // element.classList.remove("darkify_processed");
1141 return;
1142 }
1143 }
1144
1145 var has_background_img_url = false;
1146 if (backgroundImage !== "none" && backgroundImage.includes("url")) {
1147 has_background_img_url = true;
1148 if (darkify_enable_bg_image_darken === "1") {
1149 darkify_darken_bg_image(element, darken_level);
1150 }
1151 }
1152 if (
1153 backgroundColor !== "rgba(0, 0, 0, 0)" &&
1154 backgroundColor !== "rgba(255, 255, 255, 0)" &&
1155 !has_background_img_url
1156 ) {
1157 if (!element.hasAttribute("data-darkify_secondary_bg_finder")) {
1158 element.dataset.darkify_secondary_bg_finder = backgroundColor;
1159 }
1160 if (darkify_secondary_bg_color !== "") {
1161 var isSecondaryBgColorDifferent =
1162 darkify_secondary_bg_color !==
1163 element.dataset.darkify_secondary_bg_finder;
1164 if (isSecondaryBgColorDifferent) {
1165 element.classList.add("darkify_style_secondary_bg");
1166 }
1167 delete element.dataset.darkify_secondary_bg_finder;
1168 }
1169 }
1170 if (
1171 backgroundColor !== "rgba(0, 0, 0, 0)" &&
1172 color !== "rgba(0, 0, 0, 0)" &&
1173 borderColor !== "rgba(0, 0, 0, 0)" &&
1174 backgroundColor !== "rgba(255, 255, 255, 0)" &&
1175 color !== "rgba(255, 255, 255, 0)" &&
1176 borderColor !== "rgba(255, 255, 255, 0)" &&
1177 has_background_img_url === false
1178 ) {
1179 element.classList.add("darkify_style_all");
1180 } else {
1181 if (
1182 backgroundColor !== "rgba(0, 0, 0, 0)" &&
1183 color !== "rgba(0, 0, 0, 0)" &&
1184 backgroundColor !== "rgba(255, 255, 255, 0)" &&
1185 color !== "rgba(255, 255, 255, 0)" &&
1186 has_background_img_url === false
1187 ) {
1188 element.classList.add("darkify_style_bg_txt");
1189 } else {
1190 if (
1191 backgroundColor !== "rgba(0, 0, 0, 0)" &&
1192 borderColor !== "rgba(0, 0, 0, 0)" &&
1193 backgroundColor !== "rgba(255, 255, 255, 0)" &&
1194 borderColor !== "rgba(255, 255, 255, 0)" &&
1195 has_background_img_url === false
1196 ) {
1197 element.classList.add("darkify_style_bg_border");
1198 } else {
1199 if (
1200 color !== "rgba(0, 0, 0, 0)" &&
1201 borderColor !== "rgba(0, 0, 0, 0)" &&
1202 color !== "rgba(255, 255, 255, 0)" &&
1203 borderColor !== "rgba(255, 255, 255, 0)"
1204 ) {
1205 element.classList.add("darkify_style_txt_border");
1206 } else {
1207 if (
1208 backgroundColor !== "rgba(0, 0, 0, 0)" &&
1209 backgroundColor !== "rgba(255, 255, 255, 0)" &&
1210 has_background_img_url === false
1211 ) {
1212 element.classList.add("darkify_style_bg");
1213 } else {
1214 if (
1215 color !== "rgba(0, 0, 0, 0)" &&
1216 color !== "rgba(255, 255, 255, 0)"
1217 ) {
1218 element.classList.add("darkify_style_txt");
1219 } else if (
1220 borderColor !== "rgba(0, 0, 0, 0)" &&
1221 borderColor !== "rgba(255, 255, 255, 0)"
1222 ) {
1223 element.classList.add("darkify_style_border");
1224 }
1225 }
1226 }
1227 }
1228 }
1229 }
1230 if (
1231 backgroundImage !== "none" &&
1232 !has_background_img_url &&
1233 !element.classList.contains("darkify_style_all") &&
1234 !element.classList.contains("darkify_style_bg_txt") &&
1235 !element.classList.contains("darkify_style_bg_border") &&
1236 !element.classList.contains("darkify_style_bg")
1237 ) {
1238 element.classList.add("darkify_style_bg");
1239 }
1240
1241 if (nodeName === "a") {
1242 element.classList.add("darkify_style_link");
1243 }
1244
1245 if (
1246 nodeName === "input" ||
1247 nodeName === "select" ||
1248 nodeName === "textarea"
1249 ) {
1250 element.classList.add("darkify_style_form_element");
1251 }
1252
1253 const hasTargetClass = darkify_allowed_btn_class.some((cls) =>
1254 element.classList.contains(cls),
1255 );
1256
1257 if (nodeName === "button" || hasTargetClass || element.type === "submit") {
1258 element.classList.add("darkify_style_button");
1259 element.classList.remove("darkify_style_secondary_bg");
1260 element.classList.remove("darkify_style_all");
1261 element.classList.remove("darkify_style_link");
1262 }
1263
1264 if (
1265 (darkify_enable_low_image_brightness === "1" ||
1266 darkify_enable_image_grayscale === "1") &&
1267 nodeName === "img"
1268 ) {
1269 darkify_img_brightness_and_grayscale(element);
1270 }
1271
1272 if (darkify_enable_invert_inline_svg === "1" && nodeName === "svg") {
1273 darkify_invert_inline_svg(element);
1274 }
1275
1276 if (
1277 darkify_enable_low_video_brightness === "1" ||
1278 darkify_enable_video_grayscale === "1"
1279 ) {
1280 if (nodeName === "video") {
1281 darkify_video_brightness_and_grayscale(element);
1282 }
1283
1284 if (nodeName === "iframe") {
1285 const srcAttribute = element.getAttribute("src");
1286 if (srcAttribute !== null) {
1287 if (
1288 srcAttribute.includes("youtube") ||
1289 srcAttribute.includes("vimeo") ||
1290 srcAttribute.includes("dailymotion")
1291 ) {
1292 darkify_video_brightness_and_grayscale(element);
1293 }
1294 }
1295 }
1296 }
1297
1298 if (backgroundColor.includes("rgba")) {
1299 element.dataset.darkify_alpha_bg = backgroundColor;
1300 darkify_fix_background_color_alpha(element);
1301 }
1302
1303 darkify_process_pseudo_bg(element);
1304
1305 // if (old_transition !== "") {
1306 // setTimeout(function () {
1307 // element.style.setProperty("transition", old_transition);
1308 // }, 0);
1309 // }
1310
1311 setTimeout(function () {
1312 elements_class_changed.observe(element, {
1313 attributes: true,
1314 attributeFilter: ["class"],
1315 });
1316 }, 0);
1317
1318 element.classList.add("darkify_processed");
1319 }
1320
1321 function darkify_init_processes() {
1322 has_process_run_at_least_once = true;
1323 document
1324 .querySelectorAll(
1325 "* :not(head, title, link, meta, script, style, defs, filter, .darkify_processed)",
1326 )
1327 .forEach(function (element) {
1328 darkify_process_element(element);
1329 });
1330 }
1331
1332 function darkify_init_observer() {
1333 darkify_observer.observe(document, {
1334 attributes: false,
1335 childList: true,
1336 characterData: false,
1337 subtree: true,
1338 });
1339
1340 dark_mode_status_changed.observe(document.getElementsByTagName("html")[0], {
1341 attributes: true,
1342 });
1343
1344 if (document.readyState !== "loading") {
1345 if (!has_process_run_at_least_once) {
1346 darkify_init_processes();
1347 }
1348 darkify_implement_secondary_bg();
1349 darkify_apply_pseudo_bg_styles();
1350 darkify_recheck_on_css_loaded_later();
1351 } else {
1352 document.addEventListener("DOMContentLoaded", function () {
1353 if (!has_process_run_at_least_once) {
1354 darkify_init_processes();
1355 }
1356 darkify_implement_secondary_bg();
1357 darkify_apply_pseudo_bg_styles();
1358 darkify_recheck_on_css_loaded_later();
1359 });
1360 }
1361 }
1362
1363 if (darkify_check_preloading()) {
1364 document
1365 .getElementsByTagName("html")[0]
1366 .classList.add("darkify_dark_mode_enabled");
1367 darkify_init_observer();
1368
1369 darkify_process_iframes(); // �
1370 darkify proceed iframe
1371 }
1372