We use cookies to make our website more effective. By using our website you agree to our privacy policy.

Source: html/predicates.js

/**
 * html/predicates.js is part of Aloha Editor project http://www.alohaeditor.org
 *
 * Aloha Editor ● JavaScript Content Editing Library
 * Copyright (c) 2010-2015 Gentics Software GmbH, Vienna, Austria.
 * Contributors http://www.alohaeditor.org/docs/contributing.html
 */
define([], function () {
	'use strict';

	/**
	 * Void elements are elements which are not permitted to contain content.
	 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element
	 *
	 * @private
	 * @type {Object.<string, boolean>}
	 */
	var VOID_ELEMENTS = {
		'AREA'    : true,
		'BASE'    : true,
		'BR'      : true,
		'COL'     : true,
		'COMMAND' : true,
		'EMBED'   : true,
		'HR'      : true,
		'IMG'     : true,
		'INPUT'   : true,
		'KEYGEN'  : true,
		'LINK'    : true,
		'META'    : true,
		'PARAM'   : true,
		'SOURCE'  : true,
		'TRACK'   : true,
		'WBR'     : true
	};

	/**
	 * A map of node tag names which are classified as block-level element.
	 *
	 * NB: "block-level" is not technically defined for elements that are new in
	 * HTML5.
	 *
	 * @private
	 * @type {Object.<string, boolean>}
	 */
	var BLOCK_LEVEL_ELEMENTS = {
		'ADDRESS'    : true,
		'ARTICLE'    : true,
		'ASIDE'      : true,
		'AUDIO'      : true,
		'BLOCKQUOTE' : true,
		'CANVAS'     : true,
		'DD'         : true,
		'DIV'        : true,
		'DL'         : true,
		'FIELDSET'   : true,
		'FIGCAPTION' : true,
		'FIGURE'     : true,
		'FOOTER'     : true,
		'FORM'       : true,
		'H1'         : true,
		'H2'         : true,
		'H3'         : true,
		'H4'         : true,
		'H5'         : true,
		'H6'         : true,
		'HEADER'     : true,
		'HGROUP'     : true,
		'HR'         : true,
		'NOSCRIPT'   : true,
		'OL'         : true,
		'OUTPUT'     : true,
		'P'          : true,
		'PRE'        : true,
		'SECTION'    : true,
		'TABLE'      : true,
		'TFOOT'      : true,
		'UL'         : true,
		'VIDEO'      : true
	};

	/**
	 * Elements which don't constitue a word boundaries limit.
	 *
	 * @see
	 * http://www.w3.org/TR/html5/text-level-semantics.html
	 * https://developer.mozilla.org/en/docs/Web/Guide/HTML/HTML5/HTML5_element_list#Text-level_semantics
	 *
	 * @private
	 * @type {Object.<string, true>}
	 */
	var TEXT_LEVEL_SEMANTIC_ELEMENTS = {
		'A'      : true,
		'ABBR'   : true,
		'B'      : true,
		'BDI'    : true,
		'BDO'    : true,
		'BR'     : true,
		'CITE'   : true,
		'CODE'   : true,
		'DATA'   : true,
		'DFN'    : true,
		'EM'     : true,
		'I'      : true,
		'KBD'    : true,
		'MARK'   : true,
		'Q'      : true,
		'RP'     : true,
		'RT'     : true,
		'RUBY'   : true,
		'S'      : true,
		'SAMP'   : true,
		'SMALL'  : true,
		'SPAN'   : true,
		'STRONG' : true,
		'SUB'    : true,
		'SUP'    : true,
		'TIME'   : true,
		'U'      : true,
		'VAR'    : true,
		'WBR'    : true
	};

	/**
	 * Tags representing list container elements.
	 *
	 * @type {Object.<string, boolean>}
	 */
	var LIST_CONTAINERS = {
		'OL'   : true,
		'UL'   : true,
		'DL'   : true,
		'MENU' : true
	};

	/**
	 * Tags representing list item elements.
	 *
	 * @private
	 * @type {Object.<string, boolean>}
	 */
	var LIST_ITEMS = {
		'LI' : true,
		'DT' : true,
		'DD' : true
	};

	/**
	 * These element's cannot be simply unwrapped because they have dependent
	 * children.
	 *
	 * @private
	 * @see   GROUPED_CONTAINERS
	 * @param {Object.<string, boolean>}
	 */
	var GROUP_CONTAINERS = {
		'FIELDSET' : true,
		'OBJECT'   : true,
		'FIGURE'   : true,
		'AUDIO'    : true,
		'SELECT'   : true,
		'COLGROUP' : true,
		'HGROUP'   : true,
		'TABLE'    : true,
		'TBODY'    : true,
		'TR'       : true,
		'OL'       : true,
		'UL'       : true,
		'DL'       : true,
		'MENU'     : true
	};

	/**
	 * These element's cannot be simply unwrapped because they parents only
	 * allows these as their immediate child nodes.
	 *
	 * @private
	 * @see   GROUP_CONTAINERS
	 * @param {Object.<string, Array.<string>>}
	 */
	var GROUPED_ELEMENTS = {
		'LI'    : ['OL', 'UL', 'DL'],
		'DT'    : ['DL'],
		'DD'    : ['DL'],
		'TBODY' : ['TABLE'],
		'TR'    : ['TABLE', 'TBODY'],
		'TH'    : ['TABLE', 'TBODY'],
		'TD'    : ['TR', 'TH']
	};

	/**
	 * Checks if the given node is grouping container.
	 *
	 * Grouping containers include TABLE, FIELDSET, SELECT.  
	 *
	 * @see    GROUP_CONTAINERS
	 * @param  {Node} node
	 * @return {boolean}
	 * @memberOf html
	 */
	function isGroupContainer(node) {
		return GROUP_CONTAINERS[node.nodeName];
	}

	/**
	 * Checks if the given node an element that can only be a child of a group
	 * container.
	 *
	 * LI, TD are the classic cases.
	 *
	 * @see    GROUPED_CONTAINER
	 * @param  {Node} node
	 * @return {boolean}
	 * @memberOf html
	 */
	function isGroupedElement(node) {
		return !!GROUPED_ELEMENTS[node.nodeName];
	}

	/**
	 * Checks if the given node is one of the 4 list item elements.
	 *
	 * @param  {Node} node
	 * @return {boolean}
	 * @memberOf html
	 */
	function isListItem(node) {
		return !!LIST_ITEMS[node.nodeName];
	}

	/**
	 * Checks if the given node is one of the 4 list grouping containers.
	 *
	 * @param  {Node} node
	 * @return {boolean}
	 * @memberOf html
	 */
	function isListContainer(node) {
		return !!LIST_CONTAINERS[node.nodeName];
	}

	/**
	 * Checks whether `node` is the TABLE element.
	 *
	 * @param  {Node} node
	 * @return {boolean}
	 * @memberOf html
	 */
	function isTableContainer(node) {
		return node.nodeName === 'TABLE';
	}

	/**
	 * Check whether the given node is a void element type.
	 *
	 * @param  {Node} node
	 * @return {boolean}
	 * @memberOf html
	 */
	function isVoidNode(node) {
		return !!VOID_ELEMENTS[node.nodeName];
	}

	/**
	 * Similar to hasBlockStyle() except relies on the nodeName of the given
	 * node which works for attached as well as and detached nodes.
	 *
	 * Will return true if the given node is a block node type--regardless of
	 * how it is rendered.
	 *
	 * @param  {Node} node
	 * @return {boolean}
	 * @memberOf html
	 */
	function isBlockNode(node) {
		return !!BLOCK_LEVEL_ELEMENTS[node.nodeName];
	}

	/**
	 * Similar to hasInlineStyle() in the same sense as isBlockNode() is similar
	 * to hasBlockStyle().
	 *
	 * Will return true if the given node is an inline node type--regardless of
	 * how it is rendered.
	 *
	 * @param  {Node} node
	 * @return {boolean}
	 * @memberOf html
	 */
	function isInlineNode(node) {
		return !isBlockNode(node);
	}

	/**
	 * Check whether the given node is a text-level semantic element type.
	 *
	 * @param  {Node} node
	 * @return {boolean}
	 * @memberOf html
	 */
	function isTextLevelSemanticNode(node) {
		return !!TEXT_LEVEL_SEMANTIC_ELEMENTS[node.nodeName];
	}

	/**
	 * Heading tag names.
	 *
	 * @private
	 * @type {Object.<string, boolean>}
	 */
	var HEADINGS = {
		'H1' : true,
		'H2' : true,
		'H3' : true,
		'H4' : true,
		'H5' : true,
		'H6' : true
	};

	/**
	 * Whether the given node is a heading element.
	 *
	 * @param  {Node} node
	 * @return {boolean}
	 * @memberOf html
	 */
	function isHeading(node) {
		return !!HEADINGS[node.nodeName];
	}

	return {
		isBlockNode             : isBlockNode,
		isGroupContainer        : isGroupContainer,
		isGroupedElement        : isGroupedElement,
		isHeading               : isHeading,
		isInlineNode            : isInlineNode,
		isListContainer         : isListContainer,
		isListItem              : isListItem,
		isTableContainer        : isTableContainer,
		isTextLevelSemanticNode : isTextLevelSemanticNode,
		isVoidNode              : isVoidNode
	};
});
comments powered by Disqus