Skip to content

Instantly share code, notes, and snippets.

@hemanth
Forked from remy/details.js
Created April 26, 2010 15:10
Show Gist options
  • Save hemanth/379445 to your computer and use it in GitHub Desktop.
Save hemanth/379445 to your computer and use it in GitHub Desktop.
/* Author: Remy Sharp / @rem - adds <details> support to the browser */
(function (window, document) {
if ('open' in document.createElement('details')) return;
// made global by myself to be reused elsewhere
var addEvent = (function () {
if (document.addEventListener) {
return function (el, type, fn) {
if (el && el.nodeName || el === window) {
el.addEventListener(type, fn, false);
} else if (el && el.length) {
for (var i = 0; i < el.length; i++) {
addEvent(el[i], type, fn);
}
}
};
} else {
return function (el, type, fn) {
if (el && el.nodeName || el === window) {
el.attachEvent('on' + type, function () { return fn.call(el, window.event); });
} else if (el && el.length) {
for (var i = 0; i < el.length; i++) {
addEvent(el[i], type, fn);
}
}
};
}
})();
/** details support - typically in it's own script */
// find the first /real/ node
function firstNode(source) {
var node = null;
if (source.firstChild.nodeName != "#text") {
return source.firstChild;
} else {
source = source.firstChild;
do {
source = source.nextSibling;
} while (source && source.nodeName == '#text');
return source || null;
}
}
function isSummary(el) {
var nn = el.nodeName.toUpperCase();
if (nn == 'DETAILS') {
return false;
} else if (nn == 'SUMMARY') {
return true;
} else {
return isSummary(el.parentNode);
}
}
function toggleDetails(event) {
// more sigh - need to check the clicked object
var keypress = event.type == 'keypress',
target = event.target || event.srcElement;
if (keypress || isSummary(target)) {
if (keypress) {
// if it's a keypress, make sure it was enter or space
keypress = event.which || event.keyCode;
if (keypress == 32 || keypress == 13) {
// all's good, go ahead and toggle
} else {
return;
}
}
var open = this.getAttribute('open');
if (open === null) {
this.setAttribute('open', 'open');
} else {
this.removeAttribute('open');
}
// this.className = open ? 'open' : ''; // Lame
// trigger reflow (required in IE - sometimes in Safari too)
setTimeout(function () {
document.body.className = document.body.className;
}, 13);
if (keypress) {
event.preventDefault && event.preventDefault();
return false;
}
}
}
function addStyle() {
var style = document.createElement('style'),
head = document.getElementsByTagName('head')[0],
key = style.innerText === undefined ? 'textContent' : 'innerText';
var rules = ['details{display: block;}','details > *{display: none;}','details.open > *{display: block;}','details[open] > *{display: block;}', 'details > summary:first-child{display: block;cursor: pointer;}','details[open]{display: block;}'];
i = rules.length;
style[key] = rules.join('\n');
head.insertBefore(style, head.firstChild);
}
var details = document.getElementsByTagName('details'),
i = details.length,
first = null,
label = document.createElement('summary');
label.appendChild(document.createTextNode('Details'));
while (i--) {
first = firstNode(details[i]);
if (first != null && first.nodeName.toUpperCase() == 'SUMMARY') {
// we've found that there's a details label already
} else {
// first = label.cloneNode(true); // cloned nodes weren't picking up styles in IE - random
first = document.createElement('summary');
first.appendChild(document.createTextNode('Details'));
if (details[i].firstChild) {
details[i].insertBefore(first, details[i].firstChild);
} else {
details[i].appendChild(first);
}
}
first.legend = true;
first.tabIndex = 0;
}
// trigger details in case this being used on it's own
document.createElement('details');
addEvent(details, 'click', toggleDetails);
addEvent(details, 'keypress', toggleDetails);
addStyle();
})(window, document);
// minified
(function(j,c){function m(a){if('open'in document.createElement('details'))return;if(a.firstChild.nodeName!="#text")return a.firstChild;else{a=a.firstChild;do a=a.nextSibling;while(a&&a.nodeName=="#text");return a||null}}function k(a){var b=a.nodeName.toUpperCase();return b=="DETAILS"?false:b=="SUMMARY"?true:k(a.parentNode)}function l(a){var b=a.type=="keypress",e=a.target||a.srcElement;if(b||k(e)){if(b){b=a.which||a.keyCode;if(!(b==32||b==13))return}this.getAttribute("open")===null?this.setAttribute("open","open"):this.removeAttribute("open");setTimeout(function(){c.body.className=
c.body.className},13);if(b){a.preventDefault&&a.preventDefault();return false}}}function n(){var a=c.createElement("style"),b=c.getElementsByTagName("head")[0],e=a.innerText===undefined?"textContent":"innerText",d=["details{display: block;}","details > *{display: none;}","details.open > *{display: block;}","details[open] > *{display: block;}","details > summary:first-child{display: block;cursor: pointer;}","details[open]{display: block;}"];h=d.length;a[e]=d.join("\n");b.insertBefore(a,b.firstChild)}
var i=function(){return c.addEventListener?function(a,b,e){if(a&&a.nodeName||a===j)a.addEventListener(b,e,false);else if(a&&a.length)for(var d=0;d<a.length;d++)i(a[d],b,e)}:function(a,b,e){if(a&&a.nodeName||a===j)a.attachEvent("on"+b,function(){return e.call(a,j.event)});else if(a&&a.length)for(var d=0;d<a.length;d++)i(a[d],b,e)}}(),g=c.getElementsByTagName("details"),h=g.length,f=null;for(c.createElement("summary").appendChild(c.createTextNode("Details"));h--;){f=m(g[h]);if(!(f!=null&&f.nodeName.toUpperCase()==
"SUMMARY")){f=c.createElement("summary");f.appendChild(c.createTextNode("Details"));g[h].firstChild?g[h].insertBefore(f,g[h].firstChild):g[h].appendChild(f)}f.legend=true;f.tabIndex=0}c.createElement("details");i(g,"click",l);i(g,"keypress",l);n()})(window,document);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment