summaryrefslogtreecommitdiffstats
path: root/assets
diff options
context:
space:
mode:
authorBigCoke233 <hi@guhub.cn>2020-05-30 14:30:38 +0800
committerBigCoke233 <hi@guhub.cn>2020-05-30 14:30:38 +0800
commitbd0a23b052dc750db72d2b98349044a56ede2419 (patch)
treee9b1b5540f639e438bd461bec1e8bf9e9a3f0038 /assets
parent33811859eb3438db65958e9a612918643786cdeb (diff)
✨ Add: 支持解析 details 短代码,并使用 js 垫片优化兼容性
Diffstat (limited to 'assets')
-rw-r--r--assets/css/main/post.css7
-rw-r--r--assets/js/details-element-polyfill.js194
2 files changed, 201 insertions, 0 deletions
diff --git a/assets/css/main/post.css b/assets/css/main/post.css
index 6aaeff2..6a5728b 100644
--- a/assets/css/main/post.css
+++ b/assets/css/main/post.css
@@ -281,6 +281,13 @@
.post-content ol ul {
margin-top: 0;
}
+.post-content summary {
+ outline: none;
+ cursor: pointer;
+}
+.post-content summary:hover {
+ font-weight: bolder
+}
/* 加密文章 */
.post-content .protected {
display: flex;
diff --git a/assets/js/details-element-polyfill.js b/assets/js/details-element-polyfill.js
new file mode 100644
index 0000000..b651dfc
--- /dev/null
+++ b/assets/js/details-element-polyfill.js
@@ -0,0 +1,194 @@
+/*
+Details Element Polyfill 2.4.0
+Copyright © 2019 Javan Makhmali
+ */
+(function() {
+ "use strict";
+ var element = document.createElement("details");
+ var elementIsNative = typeof HTMLDetailsElement != "undefined" && element instanceof HTMLDetailsElement;
+ var support = {
+ open: "open" in element || elementIsNative,
+ toggle: "ontoggle" in element
+ };
+ var styles = '\ndetails, summary {\n display: block;\n}\ndetails:not([open]) > *:not(summary) {\n display: none;\n}\nsummary::before {\n content: "►";\n padding-right: 0.3rem;\n font-size: 0.6rem;\n cursor: default;\n}\n[open] > summary::before {\n content: "▼";\n}\n';
+ var _ref = [], forEach = _ref.forEach, slice = _ref.slice;
+ if (!support.open) {
+ polyfillStyles();
+ polyfillProperties();
+ polyfillToggle();
+ polyfillAccessibility();
+ }
+ if (support.open && !support.toggle) {
+ polyfillToggleEvent();
+ }
+ function polyfillStyles() {
+ document.head.insertAdjacentHTML("afterbegin", "<style>" + styles + "</style>");
+ }
+ function polyfillProperties() {
+ var prototype = document.createElement("details").constructor.prototype;
+ var setAttribute = prototype.setAttribute, removeAttribute = prototype.removeAttribute;
+ var open = Object.getOwnPropertyDescriptor(prototype, "open");
+ Object.defineProperties(prototype, {
+ open: {
+ get: function get() {
+ if (this.tagName == "DETAILS") {
+ return this.hasAttribute("open");
+ } else {
+ if (open && open.get) {
+ return open.get.call(this);
+ }
+ }
+ },
+ set: function set(value) {
+ if (this.tagName == "DETAILS") {
+ return value ? this.setAttribute("open", "") : this.removeAttribute("open");
+ } else {
+ if (open && open.set) {
+ return open.set.call(this, value);
+ }
+ }
+ }
+ },
+ setAttribute: {
+ value: function value(name, _value) {
+ var _this = this;
+ var call = function call() {
+ return setAttribute.call(_this, name, _value);
+ };
+ if (name == "open" && this.tagName == "DETAILS") {
+ var wasOpen = this.hasAttribute("open");
+ var result = call();
+ if (!wasOpen) {
+ var summary = this.querySelector("summary");
+ if (summary) summary.setAttribute("aria-expanded", true);
+ triggerToggle(this);
+ }
+ return result;
+ }
+ return call();
+ }
+ },
+ removeAttribute: {
+ value: function value(name) {
+ var _this2 = this;
+ var call = function call() {
+ return removeAttribute.call(_this2, name);
+ };
+ if (name == "open" && this.tagName == "DETAILS") {
+ var wasOpen = this.hasAttribute("open");
+ var result = call();
+ if (wasOpen) {
+ var summary = this.querySelector("summary");
+ if (summary) summary.setAttribute("aria-expanded", false);
+ triggerToggle(this);
+ }
+ return result;
+ }
+ return call();
+ }
+ }
+ });
+ }
+ function polyfillToggle() {
+ onTogglingTrigger(function(element) {
+ element.hasAttribute("open") ? element.removeAttribute("open") : element.setAttribute("open", "");
+ });
+ }
+ function polyfillToggleEvent() {
+ if (window.MutationObserver) {
+ new MutationObserver(function(mutations) {
+ forEach.call(mutations, function(mutation) {
+ var target = mutation.target, attributeName = mutation.attributeName;
+ if (target.tagName == "DETAILS" && attributeName == "open") {
+ triggerToggle(target);
+ }
+ });
+ }).observe(document.documentElement, {
+ attributes: true,
+ subtree: true
+ });
+ } else {
+ onTogglingTrigger(function(element) {
+ var wasOpen = element.getAttribute("open");
+ setTimeout(function() {
+ var isOpen = element.getAttribute("open");
+ if (wasOpen != isOpen) {
+ triggerToggle(element);
+ }
+ }, 1);
+ });
+ }
+ }
+ function polyfillAccessibility() {
+ setAccessibilityAttributes(document);
+ if (window.MutationObserver) {
+ new MutationObserver(function(mutations) {
+ forEach.call(mutations, function(mutation) {
+ forEach.call(mutation.addedNodes, setAccessibilityAttributes);
+ });
+ }).observe(document.documentElement, {
+ subtree: true,
+ childList: true
+ });
+ } else {
+ document.addEventListener("DOMNodeInserted", function(event) {
+ setAccessibilityAttributes(event.target);
+ });
+ }
+ }
+ function setAccessibilityAttributes(root) {
+ findElementsWithTagName(root, "SUMMARY").forEach(function(summary) {
+ var details = findClosestElementWithTagName(summary, "DETAILS");
+ summary.setAttribute("aria-expanded", details.hasAttribute("open"));
+ if (!summary.hasAttribute("tabindex")) summary.setAttribute("tabindex", "0");
+ if (!summary.hasAttribute("role")) summary.setAttribute("role", "button");
+ });
+ }
+ function eventIsSignificant(event) {
+ return !(event.defaultPrevented || event.ctrlKey || event.metaKey || event.shiftKey || event.target.isContentEditable);
+ }
+ function onTogglingTrigger(callback) {
+ addEventListener("click", function(event) {
+ if (eventIsSignificant(event)) {
+ if (event.which <= 1) {
+ var element = findClosestElementWithTagName(event.target, "SUMMARY");
+ if (element && element.parentNode && element.parentNode.tagName == "DETAILS") {
+ callback(element.parentNode);
+ }
+ }
+ }
+ }, false);
+ addEventListener("keydown", function(event) {
+ if (eventIsSignificant(event)) {
+ if (event.keyCode == 13 || event.keyCode == 32) {
+ var element = findClosestElementWithTagName(event.target, "SUMMARY");
+ if (element && element.parentNode && element.parentNode.tagName == "DETAILS") {
+ callback(element.parentNode);
+ event.preventDefault();
+ }
+ }
+ }
+ }, false);
+ }
+ function triggerToggle(element) {
+ var event = document.createEvent("Event");
+ event.initEvent("toggle", false, false);
+ element.dispatchEvent(event);
+ }
+ function findElementsWithTagName(root, tagName) {
+ return (root.tagName == tagName ? [ root ] : []).concat(typeof root.getElementsByTagName == "function" ? slice.call(root.getElementsByTagName(tagName)) : []);
+ }
+ function findClosestElementWithTagName(element, tagName) {
+ if (typeof element.closest == "function") {
+ return element.closest(tagName);
+ } else {
+ while (element) {
+ if (element.tagName == tagName) {
+ return element;
+ } else {
+ element = element.parentNode;
+ }
+ }
+ }
+ }
+ })(); \ No newline at end of file