Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

h5o

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

h5o - npm Package Compare versions

Comparing version 0.6.3 to 0.7.0

index.js

0

.grunt/grunt-gh-pages/gh-pages/dist/outliner.min.js

@@ -0,0 +0,0 @@ /**

var config = module.exports;
config["h5o-js-tests"] = {
config["browser"] = {
rootPath: ".",

@@ -19,1 +19,9 @@ environment: "browser",

};
config["jsdom"] = {
rootPath: ".",
environment: "node",
tests: [
"test/tests.jsdom.js"
]
};

647

dist/debug/outliner.debug.js

@@ -12,380 +12,363 @@ /**

(function(){
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.HTML5Outline=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
module.exports = require("./src/HTML5Outline");
var Section=function(startingNode)
{
this.sections=[];
this.startingNode = startingNode;
};
Section.prototype={
heading: false,
append: function(what)
{
what.container=this;
this.sections.push(what);
},
asHTML: function(createLinks)
{
var headingText = _sectionHeadingText(this.heading);
if (createLinks) {
headingText = '<a href="#'+_generateId(this.startingNode)+'">'
+ headingText
+ '</a>';
}
return headingText + _sectionListAsHTML(this.sections, createLinks);
}
};
},{"./src/HTML5Outline":2}],2:[function(require,module,exports){
var Section = require("./Section"),
asHtml = require("./asHtml"),
walk = require("./walk"),
utils = require("./utils");
var _sectionListAsHTML = function (sections, createLinks)
{
var retval = '';
for (var i=0; i < sections.length; i++) {
retval+='<li>'+sections[i].asHTML(createLinks)+'</li>';
}
return (retval=='' ? retval : '<ol>'+retval+'</ol>');
function arrayLast(arr) {
return arr[arr.length - 1];
}
var _sectionHeadingRank = function(section)
{
function getSectionHeadingRank(section) {
var heading = section.heading;
return isHeading(heading)
? _getHeadingElementRank(heading)
: 1; // is this true? TODO: find a reference...
}
return utils.isHeading(heading)
? utils.getHeadingElementRank(heading)
: 1; // is this true? TODO: find a reference...
};
var _sectionHeadingText = function(sectionHeading)
{
if (isHeading(sectionHeading)) {
if (_getTagName(sectionHeading)=='HGROUP') {
sectionHeading = sectionHeading.getElementsByTagName('h'+(-_getHeadingElementRank(sectionHeading)))[0];
}
// @todo: try to resolve text content from img[alt] or *[title]
return sectionHeading.textContent || sectionHeading.innerText || "<i>No text content inside "+sectionHeading.nodeName+"</i>";
var currentOutlinee, currentSection, stack;
function onEnterNode(node) {
// If the top of the stack is a heading content element - do nothing
if (utils.isHeading(arrayLast(stack))) {
return;
}
return ""+sectionHeading;
}
var _generateId = function(node)
{
var id=node.getAttribute('id');
if (id) return id;
do {
id='h5o-'+(++linkCounter);
} while (rootDocument.getElementById(id));
node.setAttribute('id', id);
return id;
}
// When entering a sectioning content element or a sectioning root element
if (utils.isSecContent(node) || utils.isSecRoot(node)) {
// If current outlinee is not null, and the current section has no heading,
// create an implied heading and let that be the heading for the current section.
// if (currentOutlinee!=null && !currentSection.heading) {
/*
TODO: is this really the way it should be done?
In my implementation, "implied heading" is always created (section.heading=false by default)
var currentOutlinee, currentSection, stack, linkCounter, rootDocument;
var walk=function (root, enter, exit) {
var node = root;
start: while (node) {
enter(node);
if (node.firstChild) {
node = node.firstChild;
continue start;
}
while (node) {
exit(node);
if (node.nextSibling) {
node = node.nextSibling;
continue start;
}
if (node == root)
node = null;
else
node = node.parentNode;
}
}
}
If I DO "create" something else here, the algorithm goes very wrong, as there's a place
where you have to check whether a "heading exists" - so - does the "implied heading" mean
there is a heading or not?
*/
// }
var enterNode=function(node)
{
// If the top of the stack is a heading content element - do nothing
if (isHeading(_arrayLast(stack))) {
return;
// If current outlinee is not null, push current outlinee onto the stack.
if (currentOutlinee != null) {
stack.push(currentOutlinee);
}
// When entering a sectioning content element or a sectioning root element
if (isSecContent(node) || isSecRoot(node)) {
// If current outlinee is not null, and the current section has no heading,
// create an implied heading and let that be the heading for the current section.
// if (currentOutlinee!=null && !currentSection.heading) {
/*
TODO: is this really the way it should be done?
In my implementation, "implied heading" is always created (section.heading=false by default)
If I DO "create" something else here, the algorithm goes very wrong, as there's a place
where you have to check whether a "heading exists" - so - does the "implied heading" mean
there is a heading or not?
*/
// }
// If current outlinee is not null, push current outlinee onto the stack.
if (currentOutlinee!=null) {
stack.push(currentOutlinee);
// Let current outlinee be the element that is being entered.
currentOutlinee = node;
// Let current section be a newly created section for the current outlinee element.
currentSection = new Section(node);
// Let there be a new outline for the new current outlinee, initialized with just the new current section as the only section in the outline.
currentOutlinee.outline = {
sections: [currentSection],
startingNode: node,
asHTML: function (createLinks) {
return asHtml(this.sections, createLinks);
}
// Let current outlinee be the element that is being entered.
currentOutlinee = node;
};
return;
}
// Let current section be a newly created section for the current outlinee element.
currentSection = new Section(node);
// If the current outlinee is null, do nothing
if (currentOutlinee == null) {
return;
}
// Let there be a new outline for the new current outlinee, initialized with just the new current section as the only section in the outline.
currentOutlinee.outline = {
sections: [currentSection],
startingNode: node,
asHTML: function(createLinks) { return _sectionListAsHTML(this.sections, createLinks); }
}
return;
}
// When entering a heading content element
if (utils.isHeading(node)) {
// If the current outlinee is null, do nothing
if (currentOutlinee==null) {
return;
}
// When entering a heading content element
if (isHeading(node)) {
// If the current section has no heading, let the element being entered be the heading for the current section.
if (!currentSection.heading) {
currentSection.heading = node;
// Otherwise, if the element being entered has a rank equal to or greater than the heading of the last section of the outline of the current outlinee,
} else if (_getHeadingElementRank(node) >= _sectionHeadingRank(_lastSection(currentOutlinee.outline))) {
// create a new section and
var newSection=new Section(node);
// append it to the outline of the current outlinee element, so that this new section is the new last section of that outline.
currentOutlinee.outline.sections.push(newSection);
// Let current section be that new section.
currentSection = newSection;
// Let the element being entered be the new heading for the current section.
currentSection.heading = node;
// If the current section has no heading, let the element being entered be the heading for the current section.
if (!currentSection.heading) {
currentSection.heading = node;
// Otherwise, if the element being entered has a rank equal to or greater than the heading of the last section of the outline of the current outlinee,
} else if (utils.getHeadingElementRank(node) >= getSectionHeadingRank(arrayLast(currentOutlinee.outline.sections))) {
// create a new section and
var newSection = new Section(node);
// append it to the outline of the current outlinee element, so that this new section is the new last section of that outline.
currentOutlinee.outline.sections.push(newSection);
// Let current section be that new section.
currentSection = newSection;
// Let the element being entered be the new heading for the current section.
currentSection.heading = node;
// Otherwise, run these substeps:
} else {
var abortSubsteps = false;
// 1. Let candidate section be current section.
var candidateSection = currentSection;
} else {
var abortSubsteps = false;
do {
// 2. If the element being entered has a rank lower than the rank of the heading of the candidate section,
if (_getHeadingElementRank(node) < _sectionHeadingRank(candidateSection)) {
// create a new section,
var newSection = new Section(node);
// 1. Let candidate section be current section.
var candidateSection = currentSection;
// and append it to candidate section. (This does not change which section is the last section in the outline.)
candidateSection.append(newSection);
// Let current section be this new section.
currentSection = newSection;
// Let the element being entered be the new heading for the current section.
currentSection.heading = node;
// Abort these substeps.
abortSubsteps = true;
}
// 3. Let new candidate section be the section that contains candidate section in the outline of current outlinee.
var newCandidateSection = candidateSection.container;
// 4. Let candidate section be new candidate section.
candidateSection = newCandidateSection;
// 5. Return to step 2.
} while (!abortSubsteps);
}
// Push the element being entered onto the stack. (This causes the algorithm to skip any descendants of the element.)
stack.push(node);
return;
do {
// 2. If the element being entered has a rank lower than the rank of the heading of the candidate section,
if (utils.getHeadingElementRank(node) < getSectionHeadingRank(candidateSection)) {
// create a new section,
var newSection = new Section(node);
// and append it to candidate section. (This does not change which section is the last section in the outline.)
candidateSection.append(newSection);
// Let current section be this new section.
currentSection = newSection;
// Let the element being entered be the new heading for the current section.
currentSection.heading = node;
// Abort these substeps.
abortSubsteps = true;
}
// 3. Let new candidate section be the section that contains candidate section in the outline of current outlinee.
var newCandidateSection = candidateSection.container;
// 4. Let candidate section be new candidate section.
candidateSection = newCandidateSection;
// 5. Return to step 2.
} while (!abortSubsteps);
}
// Do nothing.
// Push the element being entered onto the stack. (This causes the algorithm to skip any descendants of the element.)
stack.push(node);
return;
}
var exitNode=function(node)
{
// If the top of the stack is an element, and you are exiting that element
// Note: The element being exited is a heading content element.
// Pop that element from the stack.
// If the top of the stack is a heading content element - do nothing
var stackTop = _arrayLast(stack);
if (isHeading(stackTop)) {
if (stackTop == node) {
stack.pop();
}
return;
}
/************ MODIFICATION OF ORIGINAL ALGORITHM *****************/
// existing sectioning content or sectioning root
// this means, currentSection will change (and we won't get back to it)
if ((isSecContent(node) || isSecRoot(node)) && !currentSection.heading) {
currentSection.heading = '<i>Untitled ' + _getTagName(node) + '</i>';
}
/************ END MODIFICATION ***********************************/
// Do nothing.
};
// When exiting a sectioning content element, if the stack is not empty
if (isSecContent(node) && stack.length > 0) {
// Pop the top element from the stack, and let the current outlinee be that element.
currentOutlinee = stack.pop();
// Let current section be the last section in the outline of the current outlinee element.
currentSection = _lastSection(currentOutlinee.outline);
// Append the outline of the sectioning content element being exited to the current section. (This does not change which section is the last section in the outline.)
for (var i = 0; i < node.outline.sections.length; i++) {
currentSection.append(node.outline.sections[i]);
}
return;
function onExitNode(node) {
// If the top of the stack is an element, and you are exiting that element
// Note: The element being exited is a heading content element.
// Pop that element from the stack.
// If the top of the stack is a heading content element - do nothing
var stackTop = arrayLast(stack);
if (utils.isHeading(stackTop)) {
if (stackTop == node) {
stack.pop();
}
return;
}
// When exiting a sectioning root element, if the stack is not empty
if (isSecRoot(node) && stack.length > 0) {
// Pop the top element from the stack, and let the current outlinee be that element.
currentOutlinee = stack.pop();
// Let current section be the last section in the outline of the current outlinee element.
currentSection = _lastSection(currentOutlinee.outline);
/************ MODIFICATION OF ORIGINAL ALGORITHM *****************/
// existing sectioning content or sectioning root
// this means, currentSection will change (and we won't get back to it)
if ((utils.isSecContent(node) || utils.isSecRoot(node)) && !currentSection.heading) {
// Finding the deepest child: If current section has no child sections, stop these steps.
while (currentSection.sections.length > 0) {
// Let current section be the last child section of the current current section.
currentSection = _lastSection(currentSection);
// Go back to the substep labeled finding the deepest child.
}
return;
currentSection.heading = '<i>Untitled ' + utils.getTagName(node) + '</i>';
}
/************ END MODIFICATION ***********************************/
// When exiting a sectioning content element, if the stack is not empty
if (utils.isSecContent(node) && stack.length > 0) {
// Pop the top element from the stack, and let the current outlinee be that element.
currentOutlinee = stack.pop();
// Let current section be the last section in the outline of the current outlinee element.
currentSection = arrayLast(currentOutlinee.outline.sections);
// Append the outline of the sectioning content element being exited to the current section. (This does not change which section is the last section in the outline.)
for (var i = 0; i < node.outline.sections.length; i++) {
currentSection.append(node.outline.sections[i]);
}
return;
}
// When exiting a sectioning content element or a sectioning root element
if (isSecContent(node) || isSecRoot(node)) {
// Let current section be the first section in the outline of the current outlinee element.
currentSection = currentOutlinee.outline.sections[0];
// Skip to the next step in the overall set of steps. (The walk is over.)
return;
// When exiting a sectioning root element, if the stack is not empty
if (utils.isSecRoot(node) && stack.length > 0) {
// Pop the top element from the stack, and let the current outlinee be that element.
currentOutlinee = stack.pop();
// Let current section be the last section in the outline of the current outlinee element.
currentSection = arrayLast(currentOutlinee.outline.sections);
// Finding the deepest child: If current section has no child sections, stop these steps.
while (currentSection.sections.length > 0) {
// Let current section be the last child section of the current current section.
currentSection = arrayLast(currentSection.sections);
// Go back to the substep labeled finding the deepest child.
}
// If the current outlinee is null, do nothing
// Do nothing
return;
}
// minifiers will love this more than using el.tagName.toUpperCase() directly
var _getTagName = function(el)
{
return el.tagName.toUpperCase(); // upper casing due to http://ejohn.org/blog/nodename-case-sensitivity/
// When exiting a sectioning content element or a sectioning root element
if (utils.isSecContent(node) || utils.isSecRoot(node)) {
// Let current section be the first section in the outline of the current outlinee element.
currentSection = currentOutlinee.outline.sections[0];
// Skip to the next step in the overall set of steps. (The walk is over.)
return;
}
var _createTagChecker=function(regexString)
{
return function(el)
{
return isElement(el) && (new RegExp(regexString, "i")).test(_getTagName(el));
// If the current outlinee is null, do nothing
// Do nothing
};
function HTML5Outline(start) {
// Let current outlinee be null. (It holds the element whose outline is being created.)
currentOutlinee = null;
// Let current section be null. (It holds a pointer to a section, so that elements in the DOM can all be associated with a section.)
currentSection = null;
// Create a stack to hold elements, which is used to handle nesting. Initialize this stack to empty.
stack = [];
// As you walk over the DOM in tree order, trigger the first relevant step below for each element as you enter and exit it.
walk(start, onEnterNode, onExitNode);
// If the current outlinee is null, then there was no sectioning content element or sectioning root element in the DOM. There is no outline. Abort these steps.
/* @todo
if (currentOutlinee != null) {
Associate any nodes that were not associated with a section in the steps above with current outlinee as their section.
Associate all nodes with the heading of the section with which they are associated, if any.
If current outlinee is the body element, then the outline created for that element is the outline of the entire document.
}
*/
return currentOutlinee != null ? currentOutlinee.outline : null;
};
module.exports = HTML5Outline;
},{"./Section":3,"./asHtml":4,"./utils":5,"./walk":6}],3:[function(require,module,exports){
var asHtml = require("./asHtml"),
utils = require("./utils");
function sectionHeadingText(sectionHeading) {
if (utils.isHeading(sectionHeading)) {
if (utils.getTagName(sectionHeading) == 'HGROUP') {
sectionHeading = sectionHeading.getElementsByTagName('h' + (-utils.getHeadingElementRank(sectionHeading)))[0];
}
// @todo: try to resolve text content from img[alt] or *[title]
return sectionHeading.textContent || sectionHeading.innerText || "<i>No text content inside " + sectionHeading.nodeName + "</i>";
}
var isSecRoot = _createTagChecker('^BLOCKQUOTE|BODY|DETAILS|FIELDSET|FIGURE|TD$'),
isSecContent= _createTagChecker('^ARTICLE|ASIDE|NAV|SECTION$'),
isHeading = _createTagChecker('^H[1-6]|HGROUP$'),
isElement = function(obj) { return obj && obj.tagName; };
/*
var _implieadHeadings={
BLOCKQUOTE: 'Untitled quote',
BODY: 'Untitled document',
DETAILS: 'Untitled details',
FIELDSET: 'Untitled fieldset',
FIGURE: 'Untitled figure',
TD: 'Untitled cell',
ARTICLE: 'Untitled article',
ASIDE: 'Untitled sidebar',
NAV: 'Untitled navigation',
SECTION: 'Untitled section'
}
var impliedHeading=function(el)
{
return _implieadHeadings[_getTagName(el)];
}
*/
var _getHeadingElementRank = function(el)
{
var elTagName = _getTagName(el);
if (elTagName=='HGROUP') {
/* The rank of an hgroup element is the rank of the highest-ranked h1-h6 element descendant of the hgroup element, if there are any such elements, or otherwise the same as for an h1 element (the highest rank). */
for (var i=1; i <= 6; i++) {
if (el.getElementsByTagName('H'+i).length > 0)
return -i;
}
} else {
return -parseInt(elTagName.substr(1));
return "" + sectionHeading;
}
function generateId(node) {
var linkCounter = 0; // @todo: move this out somewhere else, as this is not exactly performant (but makes old tests pass)
var id = node.getAttribute('id');
if (id) return id;
do {
id = 'h5o-' + (++linkCounter);
} while (node.ownerDocument.getElementById(id)); // @todo: there's probably no document when outlining a detached fragment... is there?
node.setAttribute('id', id);
return id;
};
function Section(startingNode) {
this.sections = [];
this.startingNode = startingNode;
};
Section.prototype = {
heading: false,
append: function (what) {
what.container = this;
this.sections.push(what);
},
asHTML: function (createLinks) {
// @todo: this really belongs in a separate formatter type thing
var headingText = sectionHeadingText(this.heading);
if (createLinks) {
headingText = '<a href="#' + generateId(this.startingNode) + '">'
+ headingText
+ '</a>';
}
};
var _lastSection = function (outlineOrSection)
{
return _arrayLast(outlineOrSection.sections);
return headingText + asHtml(this.sections, createLinks);
}
};
var _arrayLast = function (arr)
{
return arr[arr.length-1];
module.exports = Section;
},{"./asHtml":4,"./utils":5}],4:[function(require,module,exports){
module.exports = function (sections, createLinks) {
var retval = '';
for (var i = 0; i < sections.length; i++) {
retval += '<li>' + sections[i].asHTML(createLinks) + '</li>';
}
HTML5Outline=function(start)
{
linkCounter=0;
// we need a document, to be able to use getElementById - @todo: figure out a better way, if there is one
rootDocument = start.ownerDocument || window.document; // @todo: how will this work in, say, Rhino, for outlining fragments?
// Let current outlinee be null. (It holds the element whose outline is being created.)
currentOutlinee=null;
// Let current section be null. (It holds a pointer to a section, so that elements in the DOM can all be associated with a section.)
currentSection=null;
// Create a stack to hold elements, which is used to handle nesting. Initialize this stack to empty.
stack=[];
// As you walk over the DOM in tree order, trigger the first relevant step below for each element as you enter and exit it.
walk(start, enterNode, exitNode);
return (retval == '' ? retval : '<ol>' + retval + '</ol>');
};
// If the current outlinee is null, then there was no sectioning content element or sectioning root element in the DOM. There is no outline. Abort these steps.
/*
if (currentOutlinee != null) {
Associate any nodes that were not associated with a section in the steps above with current outlinee as their section.
},{}],5:[function(require,module,exports){
function getTagName(el) {
return el.tagName.toUpperCase(); // upper casing due to http://ejohn.org/blog/nodename-case-sensitivity/
}
Associate all nodes with the heading of the section with which they are associated, if any.
function tagChecker(regexString) {
return function (el) {
return isElement(el) && (new RegExp(regexString, "i")).test(getTagName(el));
}
}
If current outlinee is the body element, then the outline created for that element is the outline of the entire document.
function isElement(obj) {
return obj && obj.tagName;
}
function getHeadingElementRank(el) {
var elTagName = getTagName(el);
if (elTagName == 'HGROUP') {
/* The rank of an hgroup element is the rank of the highest-ranked h1-h6 element descendant of the hgroup element, if there are any such elements, or otherwise the same as for an h1 element (the highest rank). */
for (var i = 1; i <= 6; i++) {
if (el.getElementsByTagName('H' + i).length > 0)
return -i;
}
*/
return currentOutlinee != null ? currentOutlinee.outline : null;
};
} else {
return -parseInt(elTagName.substr(1));
}
}
exports.getTagName = getTagName;
}());
exports.isSecRoot = tagChecker('^BLOCKQUOTE|BODY|DETAILS|FIELDSET|FIGURE|TD$');
exports.isSecContent = tagChecker('^ARTICLE|ASIDE|NAV|SECTION$');
exports.isHeading = tagChecker('^H[1-6]|HGROUP$');
exports.getHeadingElementRank = getHeadingElementRank;
},{}],6:[function(require,module,exports){
module.exports = function (root, enter, exit) {
var node = root;
start: while (node) {
enter(node);
if (node.firstChild) {
node = node.firstChild;
continue start;
}
while (node) {
exit(node);
if (node.nextSibling) {
node = node.nextSibling;
continue start;
}
if (node == root)
node = null;
else
node = node.parentNode;
}
}
};
},{}]},{},[1])(1)
});

@@ -11,2 +11,2 @@ /**

*/
!function(){var a=function(a){this.sections=[],this.startingNode=a};a.prototype={heading:!1,append:function(a){a.container=this,this.sections.push(a)},asHTML:function(a){var b=i(this.heading);return a&&(b='<a href="#'+j(this.startingNode)+'">'+b+"</a>"),b+g(this.sections,a)}};var b,c,d,e,f,g=function(a,b){for(var c="",d=0;d<a.length;d++)c+="<li>"+a[d].asHTML(b)+"</li>";return""==c?c:"<ol>"+c+"</ol>"},h=function(a){var b=a.heading;return r(b)?t(b):1},i=function(a){return r(a)?("HGROUP"==n(a)&&(a=a.getElementsByTagName("h"+-t(a))[0]),a.textContent||a.innerText||"<i>No text content inside "+a.nodeName+"</i>"):""+a},j=function(a){var b=a.getAttribute("id");if(b)return b;do b="h5o-"+ ++e;while(f.getElementById(b));return a.setAttribute("id",b),b},k=function(a,b,c){var d=a;a:for(;d;)if(b(d),d.firstChild)d=d.firstChild;else for(;d;){if(c(d),d.nextSibling){d=d.nextSibling;continue a}d=d==a?null:d.parentNode}},l=function(e){if(!r(v(d))){if(q(e)||p(e))return null!=b&&d.push(b),b=e,c=new a(e),void(b.outline={sections:[c],startingNode:e,asHTML:function(a){return g(this.sections,a)}});if(null!=b&&r(e)){if(c.heading)if(t(e)>=h(u(b.outline))){var f=new a(e);b.outline.sections.push(f),c=f,c.heading=e}else{var i=!1,j=c;do{if(t(e)<h(j)){var f=new a(e);j.append(f),c=f,c.heading=e,i=!0}var k=j.container;j=k}while(!i)}else c.heading=e;return void d.push(e)}}},m=function(a){var e=v(d);if(r(e))return void(e==a&&d.pop());if(!q(a)&&!p(a)||c.heading||(c.heading="<i>Untitled "+n(a)+"</i>"),q(a)&&d.length>0){b=d.pop(),c=u(b.outline);for(var f=0;f<a.outline.sections.length;f++)c.append(a.outline.sections[f])}else{if(!(p(a)&&d.length>0))return q(a)||p(a)?void(c=b.outline.sections[0]):void 0;for(b=d.pop(),c=u(b.outline);c.sections.length>0;)c=u(c)}},n=function(a){return a.tagName.toUpperCase()},o=function(a){return function(b){return s(b)&&new RegExp(a,"i").test(n(b))}},p=o("^BLOCKQUOTE|BODY|DETAILS|FIELDSET|FIGURE|TD$"),q=o("^ARTICLE|ASIDE|NAV|SECTION$"),r=o("^H[1-6]|HGROUP$"),s=function(a){return a&&a.tagName},t=function(a){var b=n(a);if("HGROUP"!=b)return-parseInt(b.substr(1));for(var c=1;6>=c;c++)if(a.getElementsByTagName("H"+c).length>0)return-c},u=function(a){return v(a.sections)},v=function(a){return a[a.length-1]};HTML5Outline=function(a){return e=0,f=a.ownerDocument||window.document,b=null,c=null,d=[],k(a,l,m),null!=b?b.outline:null}}();
!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.HTML5Outline=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b){b.exports=a("./src/HTML5Outline")},{"./src/HTML5Outline":2}],2:[function(a,b){function c(a){return a[a.length-1]}function d(a){var b=a.heading;return n.isHeading(b)?n.getHeadingElementRank(b):1}function e(a){if(!n.isHeading(c(j))){if(n.isSecContent(a)||n.isSecRoot(a))return null!=h&&j.push(h),h=a,i=new k(a),void(h.outline={sections:[i],startingNode:a,asHTML:function(a){return l(this.sections,a)}});if(null!=h&&n.isHeading(a)){if(i.heading)if(n.getHeadingElementRank(a)>=d(c(h.outline.sections))){var b=new k(a);h.outline.sections.push(b),i=b,i.heading=a}else{var e=!1,f=i;do{if(n.getHeadingElementRank(a)<d(f)){var b=new k(a);f.append(b),i=b,i.heading=a,e=!0}var g=f.container;f=g}while(!e)}else i.heading=a;return void j.push(a)}}}function f(a){var b=c(j);if(n.isHeading(b))return void(b==a&&j.pop());if(!n.isSecContent(a)&&!n.isSecRoot(a)||i.heading||(i.heading="<i>Untitled "+n.getTagName(a)+"</i>"),n.isSecContent(a)&&j.length>0){h=j.pop(),i=c(h.outline.sections);for(var d=0;d<a.outline.sections.length;d++)i.append(a.outline.sections[d])}else{if(!(n.isSecRoot(a)&&j.length>0))return n.isSecContent(a)||n.isSecRoot(a)?void(i=h.outline.sections[0]):void 0;for(h=j.pop(),i=c(h.outline.sections);i.sections.length>0;)i=c(i.sections)}}function g(a){return h=null,i=null,j=[],m(a,e,f),null!=h?h.outline:null}var h,i,j,k=a("./Section"),l=a("./asHtml"),m=a("./walk"),n=a("./utils");b.exports=g},{"./Section":3,"./asHtml":4,"./utils":5,"./walk":6}],3:[function(a,b){function c(a){return g.isHeading(a)?("HGROUP"==g.getTagName(a)&&(a=a.getElementsByTagName("h"+-g.getHeadingElementRank(a))[0]),a.textContent||a.innerText||"<i>No text content inside "+a.nodeName+"</i>"):""+a}function d(a){var b=0,c=a.getAttribute("id");if(c)return c;do c="h5o-"+ ++b;while(a.ownerDocument.getElementById(c));return a.setAttribute("id",c),c}function e(a){this.sections=[],this.startingNode=a}var f=a("./asHtml"),g=a("./utils");e.prototype={heading:!1,append:function(a){a.container=this,this.sections.push(a)},asHTML:function(a){var b=c(this.heading);return a&&(b='<a href="#'+d(this.startingNode)+'">'+b+"</a>"),b+f(this.sections,a)}},b.exports=e},{"./asHtml":4,"./utils":5}],4:[function(a,b){b.exports=function(a,b){for(var c="",d=0;d<a.length;d++)c+="<li>"+a[d].asHTML(b)+"</li>";return""==c?c:"<ol>"+c+"</ol>"}},{}],5:[function(a,b,c){function d(a){return a.tagName.toUpperCase()}function e(a){return function(b){return f(b)&&new RegExp(a,"i").test(d(b))}}function f(a){return a&&a.tagName}function g(a){var b=d(a);if("HGROUP"!=b)return-parseInt(b.substr(1));for(var c=1;6>=c;c++)if(a.getElementsByTagName("H"+c).length>0)return-c}c.getTagName=d,c.isSecRoot=e("^BLOCKQUOTE|BODY|DETAILS|FIELDSET|FIGURE|TD$"),c.isSecContent=e("^ARTICLE|ASIDE|NAV|SECTION$"),c.isHeading=e("^H[1-6]|HGROUP$"),c.getHeadingElementRank=g},{}],6:[function(a,b){b.exports=function(a,b,c){var d=a;a:for(;d;)if(b(d),d.firstChild)d=d.firstChild;else for(;d;){if(c(d),d.nextSibling){d=d.nextSibling;continue a}d=d==a?null:d.parentNode}}},{}]},{},[1])(1)});
module.exports = function (grunt) {
require('time-grunt')(grunt);
require('load-grunt-tasks')(grunt);
require("time-grunt")(grunt);
require("load-grunt-tasks")(grunt);

@@ -19,19 +19,2 @@ var VERSION = require("./package.json").version,

},
"concat": {
"outliner-js": {
"src": [
"src/notice.txt",
"src/_head.js",
"src/Section.js",
"src/Outline.js",
"src/walk.js",
"src/enterNode.js",
"src/exitNode.js",
"src/func.js",
"src/HTML5Outline.js",
"src/_foot.js"
],
"dest": "dist/debug/outliner.debug.js"
}
},
"uglify": {

@@ -62,14 +45,21 @@ "bookmarklet-js": {

files: [ "src/**" ],
tasks: [ "default" ]
tasks: [ "default", "buster:local:test", "buster:jsdom:test" ]
},
autoTest: {
files: [ "test/**" ],
tasks: [ "buster:local:test" ]
tasks: [ "buster:local:test", "buster:jsdom:test" ]
}
},
buster: {
local: {
options: {
reporter: "specification"
"local": {
"test": {
"reporter": "specification",
"config-group": "browser"
}
},
"jsdom": {
"test": {
"reporter": "specification",
"config-group": "jsdom"
}
}

@@ -82,2 +72,16 @@ },

},
browserify: {
"outliner-js": {
"src": [
"index.js"
],
"dest": "dist/debug/outliner.debug.js",
"options": {
"banner": BANNER,
"browserifyOptions": {
"standalone": "HTML5Outline"
}
}
}
},
"saucelabs-custom": {

@@ -87,15 +91,17 @@ dist: {

testname: "HTML5 outliner",
build: process.env.TRAVIS_JOB_ID || "",
browsers: [
{ browserName: 'internet explorer', platform: "Windows 8.1", version: '11' },
{ browserName: 'internet explorer', platform: "Windows 7", version: '11' },
{ browserName: 'internet explorer', platform: "Windows 7", version: '10' },
{ browserName: 'firefox', platform: "Windows 8.1" },
{ browserName: 'firefox', platform: "Windows 7" },
{ browserName: 'firefox', platform: "OS X 10.9" },
{ browserName: 'firefox', platform: "Linux" },
{ browserName: 'chrome', platform: "Windows 8.1" },
{ browserName: 'chrome', platform: "Windows 7" },
{ browserName: 'chrome', platform: "OS X 10.9" },
{ browserName: 'chrome', platform: "Linux" },
{ browserName: 'safari', platform: "OS X 10.9" }
{ browserName: "internet explorer", platform: "Windows 8.1", version: "11" },
{ browserName: "internet explorer", platform: "Windows 7", version: "11" },
{ browserName: "internet explorer", platform: "Windows 7", version: "10" },
{ browserName: "internet explorer", platform: "Windows 7", version: "9" },
{ browserName: "firefox", platform: "Windows 8.1" },
{ browserName: "firefox", platform: "Windows 7" },
{ browserName: "firefox", platform: "OS X 10.10" },
{ browserName: "firefox", platform: "Linux" },
{ browserName: "chrome", platform: "Windows 8.1" },
{ browserName: "chrome", platform: "Windows 7" },
{ browserName: "chrome", platform: "OS X 10.10" },
{ browserName: "chrome", platform: "Linux" },
{ browserName: "safari", platform: "OS X 10.10" }
],

@@ -112,6 +118,7 @@ urls: [

grunt.registerTask("default", "Clean build and minify", [ "clean:all", "concat:outliner-js", "copy:bookmarklet-js", "uglify", "_bookmarklet-release" ]);
grunt.registerTask("test", "Clean build, minify and run tests", [ "default", process.env.SAUCE_USERNAME ? "test-sauce" : "test-local" ]);
grunt.registerTask("default", "Clean build and minify", [ "clean:all", "browserify:outliner-js", "copy:bookmarklet-js", "uglify", "_bookmarklet-release" ]);
grunt.registerTask("test", "Clean build, minify and run tests", [ "default", process.env.SAUCE_USERNAME ? "test-sauce" : "test-local", "test-jsdom" ]);
grunt.registerTask("test-sauce", [ "buster-static", "saucelabs-custom" ]);
grunt.registerTask("test-local", [ "buster:local:server", "open:capture-browser", "buster:local:test" ]);
grunt.registerTask("test-jsdom", [ "buster:jsdom:test" ]);
grunt.registerTask("start-dev", [ "buster:local:server", "open:capture-browser", "watch" ]);

@@ -149,3 +156,3 @@

var resolveBin = require("resolve-bin"),
cp = require('child_process');
cp = require("child_process");

@@ -162,6 +169,6 @@ resolveBin("buster", { executable: "buster-static" }, function (e, busterStaticBinPath) {

});
busterStaticProcess.stdout.once('data', function () {
busterStaticProcess.stdout.once("data", function () {
done();
});
busterStaticProcess.stderr.on('data', function (data) {
busterStaticProcess.stderr.on("data", function (data) {
grunt.fail.fatal(data);

@@ -168,0 +175,0 @@ });

{
"name": "h5o",
"version": "0.6.3",
"version": "0.7.0",
"description": "HTML5 outliner",

@@ -28,19 +28,20 @@ "main": "index.js",

"buster-reporter-sauce": "0.1.x",
"ejs": "1.x",
"ejs": "2.x",
"grunt": "0.4.x",
"grunt-browserify": "3.x",
"grunt-buster": "0.3.x",
"grunt-cli": "0.1.x",
"grunt-contrib-clean": "0.5.x",
"grunt-contrib-concat": "0.4.x",
"grunt-contrib-copy": "0.5.x",
"grunt-contrib-uglify": "0.5.x",
"grunt-contrib-clean": "0.6.x",
"grunt-contrib-copy": "0.7.x",
"grunt-contrib-uglify": "0.7.x",
"grunt-contrib-watch": "0.6.x",
"grunt-gh-pages": "0.9.x",
"grunt-gh-pages": "0.10.x",
"grunt-open": "0.2.x",
"grunt-release": "0.7.x",
"grunt-release": "0.11.x",
"grunt-saucelabs": "8.x",
"load-grunt-tasks": "0.6.x",
"jsdom": "3.x",
"load-grunt-tasks": "3.x",
"resolve-bin": "0.3.x",
"time-grunt": "0.3.x"
"time-grunt": "1.x"
}
}

@@ -1,32 +0,232 @@

HTML5Outline=function(start)
{
linkCounter=0;
// we need a document, to be able to use getElementById - @todo: figure out a better way, if there is one
rootDocument = start.ownerDocument || window.document; // @todo: how will this work in, say, Rhino, for outlining fragments?
// Let current outlinee be null. (It holds the element whose outline is being created.)
currentOutlinee=null;
// Let current section be null. (It holds a pointer to a section, so that elements in the DOM can all be associated with a section.)
currentSection=null;
// Create a stack to hold elements, which is used to handle nesting. Initialize this stack to empty.
stack=[];
var Section = require("./Section"),
asHtml = require("./asHtml"),
walk = require("./walk"),
utils = require("./utils");
// As you walk over the DOM in tree order, trigger the first relevant step below for each element as you enter and exit it.
walk(start, enterNode, exitNode);
function arrayLast(arr) {
return arr[arr.length - 1];
}
// If the current outlinee is null, then there was no sectioning content element or sectioning root element in the DOM. There is no outline. Abort these steps.
function getSectionHeadingRank(section) {
var heading = section.heading;
return utils.isHeading(heading)
? utils.getHeadingElementRank(heading)
: 1; // is this true? TODO: find a reference...
};
var currentOutlinee, currentSection, stack;
function onEnterNode(node) {
// If the top of the stack is a heading content element - do nothing
if (utils.isHeading(arrayLast(stack))) {
return;
}
// When entering a sectioning content element or a sectioning root element
if (utils.isSecContent(node) || utils.isSecRoot(node)) {
// If current outlinee is not null, and the current section has no heading,
// create an implied heading and let that be the heading for the current section.
// if (currentOutlinee!=null && !currentSection.heading) {
/*
TODO: is this really the way it should be done?
In my implementation, "implied heading" is always created (section.heading=false by default)
If I DO "create" something else here, the algorithm goes very wrong, as there's a place
where you have to check whether a "heading exists" - so - does the "implied heading" mean
there is a heading or not?
*/
// }
// If current outlinee is not null, push current outlinee onto the stack.
if (currentOutlinee != null) {
Associate any nodes that were not associated with a section in the steps above with current outlinee as their section.
stack.push(currentOutlinee);
}
Associate all nodes with the heading of the section with which they are associated, if any.
// Let current outlinee be the element that is being entered.
currentOutlinee = node;
If current outlinee is the body element, then the outline created for that element is the outline of the entire document.
// Let current section be a newly created section for the current outlinee element.
currentSection = new Section(node);
// Let there be a new outline for the new current outlinee, initialized with just the new current section as the only section in the outline.
currentOutlinee.outline = {
sections: [currentSection],
startingNode: node,
asHTML: function (createLinks) {
return asHtml(this.sections, createLinks);
}
};
return;
}
// If the current outlinee is null, do nothing
if (currentOutlinee == null) {
return;
}
// When entering a heading content element
if (utils.isHeading(node)) {
// If the current section has no heading, let the element being entered be the heading for the current section.
if (!currentSection.heading) {
currentSection.heading = node;
// Otherwise, if the element being entered has a rank equal to or greater than the heading of the last section of the outline of the current outlinee,
} else if (utils.getHeadingElementRank(node) >= getSectionHeadingRank(arrayLast(currentOutlinee.outline.sections))) {
// create a new section and
var newSection = new Section(node);
// append it to the outline of the current outlinee element, so that this new section is the new last section of that outline.
currentOutlinee.outline.sections.push(newSection);
// Let current section be that new section.
currentSection = newSection;
// Let the element being entered be the new heading for the current section.
currentSection.heading = node;
// Otherwise, run these substeps:
} else {
var abortSubsteps = false;
// 1. Let candidate section be current section.
var candidateSection = currentSection;
do {
// 2. If the element being entered has a rank lower than the rank of the heading of the candidate section,
if (utils.getHeadingElementRank(node) < getSectionHeadingRank(candidateSection)) {
// create a new section,
var newSection = new Section(node);
// and append it to candidate section. (This does not change which section is the last section in the outline.)
candidateSection.append(newSection);
// Let current section be this new section.
currentSection = newSection;
// Let the element being entered be the new heading for the current section.
currentSection.heading = node;
// Abort these substeps.
abortSubsteps = true;
}
// 3. Let new candidate section be the section that contains candidate section in the outline of current outlinee.
var newCandidateSection = candidateSection.container;
// 4. Let candidate section be new candidate section.
candidateSection = newCandidateSection;
// 5. Return to step 2.
} while (!abortSubsteps);
}
*/
return currentOutlinee != null ? currentOutlinee.outline : null;
};
// Push the element being entered onto the stack. (This causes the algorithm to skip any descendants of the element.)
stack.push(node);
return;
}
// Do nothing.
};
function onExitNode(node) {
// If the top of the stack is an element, and you are exiting that element
// Note: The element being exited is a heading content element.
// Pop that element from the stack.
// If the top of the stack is a heading content element - do nothing
var stackTop = arrayLast(stack);
if (utils.isHeading(stackTop)) {
if (stackTop == node) {
stack.pop();
}
return;
}
/************ MODIFICATION OF ORIGINAL ALGORITHM *****************/
// existing sectioning content or sectioning root
// this means, currentSection will change (and we won't get back to it)
if ((utils.isSecContent(node) || utils.isSecRoot(node)) && !currentSection.heading) {
currentSection.heading = '<i>Untitled ' + utils.getTagName(node) + '</i>';
}
/************ END MODIFICATION ***********************************/
// When exiting a sectioning content element, if the stack is not empty
if (utils.isSecContent(node) && stack.length > 0) {
// Pop the top element from the stack, and let the current outlinee be that element.
currentOutlinee = stack.pop();
// Let current section be the last section in the outline of the current outlinee element.
currentSection = arrayLast(currentOutlinee.outline.sections);
// Append the outline of the sectioning content element being exited to the current section. (This does not change which section is the last section in the outline.)
for (var i = 0; i < node.outline.sections.length; i++) {
currentSection.append(node.outline.sections[i]);
}
return;
}
// When exiting a sectioning root element, if the stack is not empty
if (utils.isSecRoot(node) && stack.length > 0) {
// Pop the top element from the stack, and let the current outlinee be that element.
currentOutlinee = stack.pop();
// Let current section be the last section in the outline of the current outlinee element.
currentSection = arrayLast(currentOutlinee.outline.sections);
// Finding the deepest child: If current section has no child sections, stop these steps.
while (currentSection.sections.length > 0) {
// Let current section be the last child section of the current current section.
currentSection = arrayLast(currentSection.sections);
// Go back to the substep labeled finding the deepest child.
}
return;
}
// When exiting a sectioning content element or a sectioning root element
if (utils.isSecContent(node) || utils.isSecRoot(node)) {
// Let current section be the first section in the outline of the current outlinee element.
currentSection = currentOutlinee.outline.sections[0];
// Skip to the next step in the overall set of steps. (The walk is over.)
return;
}
// If the current outlinee is null, do nothing
// Do nothing
};
function HTML5Outline(start) {
// Let current outlinee be null. (It holds the element whose outline is being created.)
currentOutlinee = null;
// Let current section be null. (It holds a pointer to a section, so that elements in the DOM can all be associated with a section.)
currentSection = null;
// Create a stack to hold elements, which is used to handle nesting. Initialize this stack to empty.
stack = [];
// As you walk over the DOM in tree order, trigger the first relevant step below for each element as you enter and exit it.
walk(start, onEnterNode, onExitNode);
// If the current outlinee is null, then there was no sectioning content element or sectioning root element in the DOM. There is no outline. Abort these steps.
/* @todo
if (currentOutlinee != null) {
Associate any nodes that were not associated with a section in the steps above with current outlinee as their section.
Associate all nodes with the heading of the section with which they are associated, if any.
If current outlinee is the body element, then the outline created for that element is the outline of the entire document.
}
*/
return currentOutlinee != null ? currentOutlinee.outline : null;
};
module.exports = HTML5Outline;

@@ -1,68 +0,52 @@

var Section=function(startingNode)
{
this.sections=[];
var asHtml = require("./asHtml"),
utils = require("./utils");
function sectionHeadingText(sectionHeading) {
if (utils.isHeading(sectionHeading)) {
if (utils.getTagName(sectionHeading) == 'HGROUP') {
sectionHeading = sectionHeading.getElementsByTagName('h' + (-utils.getHeadingElementRank(sectionHeading)))[0];
}
// @todo: try to resolve text content from img[alt] or *[title]
return sectionHeading.textContent || sectionHeading.innerText || "<i>No text content inside " + sectionHeading.nodeName + "</i>";
}
return "" + sectionHeading;
}
function generateId(node) {
var linkCounter = 0; // @todo: move this out somewhere else, as this is not exactly performant (but makes old tests pass)
var id = node.getAttribute('id');
if (id) return id;
do {
id = 'h5o-' + (++linkCounter);
} while (node.ownerDocument.getElementById(id)); // @todo: there's probably no document when outlining a detached fragment... is there?
node.setAttribute('id', id);
return id;
};
function Section(startingNode) {
this.sections = [];
this.startingNode = startingNode;
};
Section.prototype={
Section.prototype = {
heading: false,
append: function(what)
{
what.container=this;
append: function (what) {
what.container = this;
this.sections.push(what);
},
asHTML: function(createLinks)
{
var headingText = _sectionHeadingText(this.heading);
asHTML: function (createLinks) {
// @todo: this really belongs in a separate formatter type thing
var headingText = sectionHeadingText(this.heading);
if (createLinks) {
headingText = '<a href="#'+_generateId(this.startingNode)+'">'
+ headingText
+ '</a>';
headingText = '<a href="#' + generateId(this.startingNode) + '">'
+ headingText
+ '</a>';
}
return headingText + _sectionListAsHTML(this.sections, createLinks);
return headingText + asHtml(this.sections, createLinks);
}
};
var _sectionListAsHTML = function (sections, createLinks)
{
var retval = '';
for (var i=0; i < sections.length; i++) {
retval+='<li>'+sections[i].asHTML(createLinks)+'</li>';
}
return (retval=='' ? retval : '<ol>'+retval+'</ol>');
}
var _sectionHeadingRank = function(section)
{
var heading = section.heading;
return isHeading(heading)
? _getHeadingElementRank(heading)
: 1; // is this true? TODO: find a reference...
}
var _sectionHeadingText = function(sectionHeading)
{
if (isHeading(sectionHeading)) {
if (_getTagName(sectionHeading)=='HGROUP') {
sectionHeading = sectionHeading.getElementsByTagName('h'+(-_getHeadingElementRank(sectionHeading)))[0];
}
// @todo: try to resolve text content from img[alt] or *[title]
return sectionHeading.textContent || sectionHeading.innerText || "<i>No text content inside "+sectionHeading.nodeName+"</i>";
}
return ""+sectionHeading;
}
var _generateId = function(node)
{
var id=node.getAttribute('id');
if (id) return id;
do {
id='h5o-'+(++linkCounter);
} while (rootDocument.getElementById(id));
node.setAttribute('id', id);
return id;
}
module.exports = Section;

@@ -1,23 +0,21 @@

var currentOutlinee, currentSection, stack, linkCounter, rootDocument;
var walk=function (root, enter, exit) {
var node = root;
start: while (node) {
enter(node);
if (node.firstChild) {
node = node.firstChild;
module.exports = function (root, enter, exit) {
var node = root;
start: while (node) {
enter(node);
if (node.firstChild) {
node = node.firstChild;
continue start;
}
while (node) {
exit(node);
if (node.nextSibling) {
node = node.nextSibling;
continue start;
}
while (node) {
exit(node);
if (node.nextSibling) {
node = node.nextSibling;
continue start;
}
if (node == root)
node = null;
else
node = node.parentNode;
}
if (node == root)
node = null;
else
node = node.parentNode;
}
}
};
(function () {
var doc = this.document || this.jsdomDocument;
var contextPath = this.contextPath || buster.env.contextPath || "";
var expect = buster.referee.expect,

@@ -19,3 +23,3 @@ describe = buster.spec.describe,

it("non-sectioning element outlining", function () {
var actual = HTML5Outline(document.createElement('div'));
var actual = HTML5Outline(doc.createElement('div'));

@@ -26,4 +30,4 @@ expect(actual).toBeNull("Outline for an empty DIV should be null");

it("section inside a div - not starting with secRoot", function () {
var div = document.createElement('div');
div.appendChild(document.createElement('section'));
var div = doc.createElement('div');
div.appendChild(doc.createElement('section'));

@@ -36,5 +40,5 @@ expect(HTML5Outline(div).asHTML())

it("two sections inside a div - not starting with secRoot", function () {
var div = document.createElement('div');
div.appendChild(document.createElement('section'));
div.appendChild(document.createElement('section'));
var div = doc.createElement('div');
div.appendChild(doc.createElement('section'));
div.appendChild(doc.createElement('section'));

@@ -47,7 +51,7 @@ expect(HTML5Outline(div).asHTML())

it("some headings", function () {
var div = document.createElement('div');
var heading = document.createElement('h1');
var div = doc.createElement('div');
var heading = doc.createElement('h1');
heading.innerHTML = "Test";
div.appendChild(heading);
div.appendChild(document.createElement('section'));
div.appendChild(doc.createElement('section'));

@@ -71,9 +75,7 @@ expect(HTML5Outline(div).asHTML())

var docIframe = document.createElement("iframe"),
outIframe = document.createElement("iframe"),
out,
doc = out = false;
var inputIframe = doc.createElement("iframe"),
outputIframe = doc.createElement("iframe"),
outputBody,
inputBody = outputBody = false;
var contextPath = buster.env.contextPath || "";
var createLinks = (testID.substring(0, 6) == 'links_');

@@ -83,26 +85,26 @@

var runTest = function () {
var expected = cleanWhiteSpace(out.innerHTML);
var actual = cleanWhiteSpace(HTML5Outline(doc).asHTML(createLinks));
var expected = cleanWhiteSpace(outputBody.innerHTML);
var actual = cleanWhiteSpace(HTML5Outline(inputBody).asHTML(createLinks));
expect(actual).toEqual(expected, "Comparison for: " + testID);
docIframe.parentNode.removeChild(docIframe);
outIframe.parentNode.removeChild(outIframe);
inputIframe.parentNode.removeChild(inputIframe);
outputIframe.parentNode.removeChild(outputIframe);
done();
};
docIframe.onload = function () {
doc = docIframe.contentWindow.document.body;
if (out) runTest();
inputIframe.onload = function () {
inputBody = inputIframe.contentWindow.document.body;
if (outputBody) runTest();
};
docIframe.src = (contextPath + "/test/" + testID + ".doc.html");
inputIframe.src = (contextPath + "/test/" + testID + ".doc.html");
outIframe.onload = function () {
out = outIframe.contentWindow.document.body;
if (doc) runTest();
outputIframe.onload = function () {
outputBody = outputIframe.contentWindow.document.body;
if (inputBody) runTest();
};
outIframe.src = (contextPath + "/test/" + testID + ".out.html");
outputIframe.src = (contextPath + "/test/" + testID + ".out.html");
document.body.appendChild(docIframe);
document.body.appendChild(outIframe);
doc.body.appendChild(inputIframe);
doc.body.appendChild(outputIframe);
}

@@ -109,0 +111,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc