HackMD/public/vendor/gist-embed.js
2015-05-15 12:58:13 +08:00

184 lines
5.9 KiB
JavaScript

// author: Blair Vanderhoof
// https://github.com/blairvanderhoof/gist-embed
// version 2.0
(function($) {
function getLineNumbers(lineRangeString) {
var lineNumbers = [], range, lineNumberSections;
if (typeof lineRangeString === 'number') {
lineNumbers.push(lineRangeString);
} else {
lineNumberSections = lineRangeString.split(',');
for (var i = 0; i < lineNumberSections.length; i++) {
range = lineNumberSections[i].split('-');
if (range.length === 2) {
for (var j = parseInt(range[0], 10); j <= range[1]; j++) {
lineNumbers.push(j);
}
} else if (range.length === 1) {
lineNumbers.push(parseInt(range[0], 10));
}
}
}
return lineNumbers;
}
$.fn.gist = function(callback) {
return this.each(function() {
var $elem = $(this),
id,
url,
file,
lines,
highlightLines,
hideFooterOption,
hideLineNumbersOption,
showLoading,
data = {};
// make block level so loading text shows properly
$elem.css('display', 'block');
id = $elem.data('gist-id') || '';
file = $elem.data('gist-file');
hideFooterOption = $elem.data('gist-hide-footer') === true;
hideLineNumbersOption = $elem.data('gist-hide-line-numbers') === true;
lines = $elem.data('gist-line');
highlightLines = $elem.data('gist-highlight-line');
showLoading = $elem.data('gist-show-loading') !== undefined ?
$elem.data('gist-show-loading') : true;
if (file) {
data.file = file;
}
// if the id doesn't exist, then ignore the code block
if (!id) return false;
url = 'https://gist.github.com/' + id + '.json';
// loading
if (showLoading) {
$elem.html('Loading gist ' + url + (data.file ? ', file: ' + data.file : '') + '...');
}
// request the json version of this gist
$.ajax({
url: url,
data: data,
dataType: 'jsonp',
timeout: 10000,
success: function(response) {
var linkTag,
head,
lineNumbers,
highlightLineNumbers,
$responseDiv;
// the html payload is in the div property
if (response && response.div) {
// github returns /assets/embed-id.css now, but let's be sure about that
if (response.stylesheet && response.stylesheet.indexOf('http') !== 0) {
// add leading slash if missing
if (response.stylesheet.indexOf('/') !== 0) {
response.stylesheet = '/' + response.stylesheet;
}
response.stylesheet = 'https://gist.github.com' + response.stylesheet;
}
// add the stylesheet if it does not exist
if (response.stylesheet && $('link[href="' + response.stylesheet + '"]').length === 0) {
linkTag = document.createElement('link');
head = document.getElementsByTagName('head')[0];
linkTag.type = 'text/css';
linkTag.rel = 'stylesheet';
linkTag.href = response.stylesheet;
head.insertBefore(linkTag, head.firstChild);
}
// refernce to div
$responseDiv = $(response.div);
// remove id for uniqueness constraints
$responseDiv.removeAttr('id');
$elem.html('').append($responseDiv);
// option to highlight lines
if (highlightLines) {
highlightLineNumbers = getLineNumbers(highlightLines);
// we need to set the line-data td to 100% so the highlight expands the whole line
$responseDiv.find('td.line-data').css({
'width': '100%'
});
// find all .line divs (acutal code lines) that match the highlightLines and add the highlight class
$responseDiv.find('.line').each(function(index) {
if ($.inArray(index + 1, highlightLineNumbers) !== -1) {
$(this).css({
'background-color': 'rgb(255, 255, 204)'
});
}
});
}
// if user provided a line param, get the line numbers baesed on the criteria
if (lines) {
lineNumbers = getLineNumbers(lines);
// find all .line divs (acutal code lines) and remove them if they don't exist in the line param
$responseDiv.find('.line').each(function(index) {
if (($.inArray(index + 1, lineNumbers)) === -1) {
$(this).remove();
}
});
// find all .line-number divs (numbers on the gutter) and remove them if they don't exist in the line param
$responseDiv.find('.line-number').each(function(index) {
if (($.inArray(index + 1, lineNumbers)) === -1) {
$(this).remove();
}
});
}
// option to remove footer
if (hideFooterOption) {
$responseDiv.find('.gist-meta').remove();
// present a uniformed border when footer is hidden
$responseDiv.find('.gist-data').css("border-bottom", "0px");
$responseDiv.find('.gist-file').css("border-bottom", "1px solid #ddd");
}
// option to remove
if (hideLineNumbersOption) {
$responseDiv.find('.line-numbers').remove();
}
} else {
$elem.html('Failed loading gist ' + url);
}
},
error: function(jqXHR, textStatus) {
$elem.html('Failed loading gist ' + url + ': ' + textStatus);
},
complete: function() {
if(callback)
callback();
}
});
});
};
$(function() {
// find all elements containing "data-gist-id" attribute.
$('[data-gist-id]').gist();
});
})(jQuery);