202 lines
5.3 KiB
JavaScript
202 lines
5.3 KiB
JavaScript
(function ($) {
|
|
"use strict";
|
|
|
|
// Make sure regex patterns are only parsed once
|
|
var $newLinePattern = /\{n}/g,
|
|
$spacePattern = /\{s}/g,
|
|
$tabPattern = /\{t}/g,
|
|
$whiteSpacePattern = /^(?:\s+)?$/g,
|
|
$inputTagPattern = /<input(.*?)>/g,
|
|
$optionClosingTagPattern = />(?:\s+)?<\/option>/g,
|
|
$htmlAttributeSpacingPattern = /(\s+)([^id][a-z_\-]+="(?:.*?)")/ig;
|
|
|
|
// Just kill form submission
|
|
$.qs('form').onsubmit = function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
console.log("Form 'submit' event fired.");
|
|
|
|
return false;
|
|
};
|
|
|
|
var format = {
|
|
/**
|
|
* Format the display of an input element, and align the attributes
|
|
* on separate lines
|
|
*
|
|
* @param {HTMLInputElement} formElement
|
|
* @return {string}
|
|
*/
|
|
input: function (formElement) {
|
|
// Let's do some ugly DOM manipulation to make the output of the
|
|
// highlighted have lined up attributes.
|
|
// For the spacing, we replace normal whitespace characters with
|
|
// {x} placeholders so the highlighter doesn't mangle them
|
|
var formElementSpaces = '{s}'.repeat(formElement.tagName.length + 2);
|
|
var formElementReplace = '{n}' + formElementSpaces;
|
|
var formElementHTML = formElement.outerHTML
|
|
.trim()
|
|
.replace($inputTagPattern, '<input$1 />')
|
|
.replace($htmlAttributeSpacingPattern, formElementReplace + '$2');
|
|
|
|
return formElementHTML;
|
|
},
|
|
/**
|
|
* Format the display of an option element
|
|
*
|
|
* @param {HTMLOptionElement} formElement
|
|
* @return {string}
|
|
*/
|
|
option: function (formElement) {
|
|
var raw = format.generic(formElement);
|
|
|
|
if (hasHtmlChildren(formElement) && formElement.childNodes.length > 0) {
|
|
return raw;
|
|
}
|
|
|
|
raw = raw.replace($whiteSpacePattern, '');
|
|
return raw.replace($optionClosingTagPattern, ' />');
|
|
},
|
|
/**
|
|
* Format the display of elements without specific formatting methods
|
|
*
|
|
* @param {HTMLElement} formElement
|
|
* @return {string}
|
|
*/
|
|
generic: function (formElement) {
|
|
return formElement.outerHTML.trim();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Format the current element
|
|
*
|
|
* @param {HTMLElement} formElement
|
|
* @param {number} i
|
|
* @return string
|
|
*/
|
|
function formatElement (formElement, i) {
|
|
var elementPrefix = (i > 0)
|
|
? '{n}' + '{t}'.repeat(i)
|
|
: '';
|
|
|
|
if (formElement.nodeType === 3) {
|
|
return elementPrefix + formElement.nodeValue;
|
|
}
|
|
|
|
var tagName = formElement.tagName.toLowerCase();
|
|
var formattingMethod = (Object.keys(format).indexOf(tagName) !== -1)
|
|
? format[tagName]
|
|
: format.generic;
|
|
|
|
return elementPrefix + formattingMethod(formElement);
|
|
}
|
|
|
|
/**
|
|
* Check whether an element has an other elements as children
|
|
*
|
|
* @param {HTMLElement} element
|
|
* @return {boolean}
|
|
*/
|
|
function hasHtmlChildren (element) {
|
|
var x = 0;
|
|
var node;
|
|
var numChildren = element.childNodes.length;
|
|
|
|
if (numChildren === 0) {
|
|
return false;
|
|
}
|
|
|
|
for (; x < numChildren; x++) {
|
|
node = element.childNodes.item(x);
|
|
|
|
// Only count as a child if the node is an element
|
|
if (node.nodeType === 1) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Recursively format the form elements for better alignment
|
|
*
|
|
* @param {HTMLElement} formElement
|
|
* @param {number} level
|
|
* @return {string}
|
|
*/
|
|
function formatHtml(formElement, level) {
|
|
level = level || 0;
|
|
|
|
var children = $.toArray(formElement.childNodes);
|
|
var hasChildren = hasHtmlChildren(formElement);
|
|
|
|
var rawChildren = formElement.innerHTML;
|
|
var formattedHTML = formatElement(formElement, level);
|
|
|
|
// If there are no children, just return the formatted element
|
|
if (!hasChildren) {
|
|
return formattedHTML;
|
|
}
|
|
|
|
children = children.filter(function (node) {
|
|
// Discard text nodes if they only contain whitespace
|
|
if (node.nodeType === 3 && node.nodeValue.match($whiteSpacePattern)) {
|
|
return false;
|
|
}
|
|
|
|
// Keep other nodes
|
|
return true;
|
|
});
|
|
|
|
level++;
|
|
var newChildrenHTML = children.reduce(function (prevHTML, node) {
|
|
return prevHTML + formatHtml(node, level);
|
|
}, '');
|
|
|
|
// Format those closing tags
|
|
if (level > 0 && hasChildren) {
|
|
newChildrenHTML += '{n}' + '{t}'.repeat(level - 1);
|
|
}
|
|
|
|
formattedHTML = formattedHTML.replace(rawChildren, newChildrenHTML);
|
|
|
|
return formattedHTML;
|
|
}
|
|
|
|
// Get each form field's html and syntax highlight it
|
|
$.getByClass('form-field').forEach(function(parent) {
|
|
// Setup up the highligher
|
|
var hl = new DlHighlight({lang: 'html'});
|
|
|
|
var labelHTML = formatHtml($.qs('label', parent), 0);
|
|
var formElements = $.qsa('button, input, datalist, keygen, meter, output, progress, select, textarea', parent);
|
|
|
|
var formElementHTML = '';
|
|
formElements.forEach(function (formElement) {
|
|
formElementHTML += '{n}{n}' + formatHtml(formElement, 0);
|
|
});
|
|
|
|
// Join the label markup with the form element markup
|
|
var formCode = labelHTML + formElementHTML.trim();
|
|
|
|
// Now replace the placeholders with proper whitespace equvalent markup
|
|
var highLighted = hl.doItNow(formCode);
|
|
highLighted = $.replaceMultiple(highLighted, [
|
|
[$newLinePattern, '<br />'],
|
|
[$spacePattern, ' '],
|
|
[$tabPattern, ' '.repeat(4)]
|
|
]);
|
|
|
|
// Piece together the HTML for the prettier HTML examples
|
|
var codeElement = document.createElement('code');
|
|
codeElement.className = 'DlHighlight html';
|
|
codeElement.innerHTML = highLighted;
|
|
|
|
// Append the prettified HTML to the parent element
|
|
parent.appendChild(codeElement);
|
|
});
|
|
|
|
}(doc)); |