mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
add discourse-details plugin
This commit is contained in:
58
plugins/discourse-details/assets/javascripts/details.js
Normal file
58
plugins/discourse-details/assets/javascripts/details.js
Normal file
@@ -0,0 +1,58 @@
|
||||
(function(document, $) {
|
||||
|
||||
// cf. http://mths.be/details
|
||||
var hasNativeSupport = (function(doc) {
|
||||
var fake, el = doc.createElement("details");
|
||||
// fail-fast
|
||||
if (!("open" in el)) { return false; }
|
||||
// figure out a root node
|
||||
var root = doc.body || (function() {
|
||||
var de = doc.documentElement;
|
||||
fake = true;
|
||||
return de.insertBefore(doc.createElement("body"), de.firstElementChild || de.firstChild);
|
||||
})();
|
||||
// setup test element
|
||||
el.innerHTML = "<summary>a</summary>b";
|
||||
el.style.display = "block";
|
||||
// add test element to the root node
|
||||
root.appendChild(el);
|
||||
// can we open it?
|
||||
var diff = el.offsetHeight;
|
||||
el.open = true;
|
||||
diff = diff !== el.offsetHeight;
|
||||
// cleanup
|
||||
root.removeChild(el);
|
||||
if (fake) { root.parentNode.removeChild(root); }
|
||||
// return the result
|
||||
return diff;
|
||||
})(document);
|
||||
|
||||
function toggleOpen($details) {
|
||||
$details.toggleClass("open");
|
||||
}
|
||||
|
||||
$.fn.details = function() {
|
||||
if (hasNativeSupport) { return this; }
|
||||
|
||||
return this.each(function() {
|
||||
var $details = $(this),
|
||||
$firstSummary = $("summary", $details).first();
|
||||
|
||||
$firstSummary.prop("tabIndex", 0);
|
||||
|
||||
$firstSummary.on("keydown", function(event) {
|
||||
if (event.keyCode === 32 /* SPACE */ || event.keyCode === 13 /* ENTER */) {
|
||||
toggleOpen($details);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
$firstSummary.on("click", function() {
|
||||
$firstSummary.focus();
|
||||
toggleOpen($details);
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
})(document, jQuery);
|
||||
@@ -0,0 +1,26 @@
|
||||
(function() {
|
||||
|
||||
function insertDetails(_, summary, details) {
|
||||
return "<details><summary>" + summary + "</summary>" + details + "</details>";
|
||||
}
|
||||
|
||||
// replace all [details] BBCode with HTML 5.1 equivalent
|
||||
function replaceDetails(text) {
|
||||
text = text || "";
|
||||
|
||||
while (text !== (text = text.replace(/\[details=([^\]]+)\]((?:(?!\[details=[^\]]+\]|\[\/details\])[\S\s])*)\[\/details\]/ig, insertDetails)));
|
||||
|
||||
// add new lines to make sure we *always* have a <p> element after </summary> and around </details>
|
||||
// otherwise we can't hide the content since we can't target text nodes via CSS
|
||||
return text.replace(/<\/summary>/ig, "</summary>\n\n")
|
||||
.replace(/<\/details>/ig, "\n\n</details>\n\n");
|
||||
}
|
||||
|
||||
Discourse.Dialect.addPreProcessor(function(text) {
|
||||
if (Discourse.SiteSettings.details_enabled) {
|
||||
text = replaceDetails(text);
|
||||
}
|
||||
return text;
|
||||
});
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,10 @@
|
||||
import { decorateCooked } from "discourse/lib/plugin-api";
|
||||
|
||||
export default {
|
||||
name: "apply-details",
|
||||
|
||||
initialize(container) {
|
||||
decorateCooked(container, $elem => $("details", $elem).details());
|
||||
}
|
||||
|
||||
};
|
||||
38
plugins/discourse-details/assets/stylesheets/details.scss
Normal file
38
plugins/discourse-details/assets/stylesheets/details.scss
Normal file
@@ -0,0 +1,38 @@
|
||||
details {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
details > *,
|
||||
details .lightbox-wrapper {
|
||||
display: none;
|
||||
}
|
||||
|
||||
summary:first-of-type {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
}
|
||||
|
||||
summary:before {
|
||||
content: '\25BA';
|
||||
margin-right: .25em;
|
||||
}
|
||||
|
||||
details[open] > summary:before,
|
||||
details.open > summary:before {
|
||||
content: '\25BC';
|
||||
}
|
||||
|
||||
details[open] > summary:first-of-type ~ *,
|
||||
details.open > summary:first-of-type ~ * {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* hide native indicator */
|
||||
summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* FF: hide div generated by lazyYT plugin */
|
||||
details .lazyYT-container {
|
||||
display: none;
|
||||
}
|
||||
Reference in New Issue
Block a user