You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							260 lines
						
					
					
						
							9.2 KiB
						
					
					
				
			
		
		
	
	
							260 lines
						
					
					
						
							9.2 KiB
						
					
					
				'use strict'; | 
						|
 | 
						|
var Tokenizer = require('../tokenizer'), | 
						|
    HTML = require('./html'); | 
						|
 | 
						|
//Aliases | 
						|
var $ = HTML.TAG_NAMES, | 
						|
    NS = HTML.NAMESPACES, | 
						|
    ATTRS = HTML.ATTRS; | 
						|
 | 
						|
 | 
						|
//MIME types | 
						|
var MIME_TYPES = { | 
						|
    TEXT_HTML: 'text/html', | 
						|
    APPLICATION_XML: 'application/xhtml+xml' | 
						|
}; | 
						|
 | 
						|
//Attributes | 
						|
var DEFINITION_URL_ATTR = 'definitionurl', | 
						|
    ADJUSTED_DEFINITION_URL_ATTR = 'definitionURL', | 
						|
    SVG_ATTRS_ADJUSTMENT_MAP = { | 
						|
        'attributename': 'attributeName', | 
						|
        'attributetype': 'attributeType', | 
						|
        'basefrequency': 'baseFrequency', | 
						|
        'baseprofile': 'baseProfile', | 
						|
        'calcmode': 'calcMode', | 
						|
        'clippathunits': 'clipPathUnits', | 
						|
        'diffuseconstant': 'diffuseConstant', | 
						|
        'edgemode': 'edgeMode', | 
						|
        'filterunits': 'filterUnits', | 
						|
        'glyphref': 'glyphRef', | 
						|
        'gradienttransform': 'gradientTransform', | 
						|
        'gradientunits': 'gradientUnits', | 
						|
        'kernelmatrix': 'kernelMatrix', | 
						|
        'kernelunitlength': 'kernelUnitLength', | 
						|
        'keypoints': 'keyPoints', | 
						|
        'keysplines': 'keySplines', | 
						|
        'keytimes': 'keyTimes', | 
						|
        'lengthadjust': 'lengthAdjust', | 
						|
        'limitingconeangle': 'limitingConeAngle', | 
						|
        'markerheight': 'markerHeight', | 
						|
        'markerunits': 'markerUnits', | 
						|
        'markerwidth': 'markerWidth', | 
						|
        'maskcontentunits': 'maskContentUnits', | 
						|
        'maskunits': 'maskUnits', | 
						|
        'numoctaves': 'numOctaves', | 
						|
        'pathlength': 'pathLength', | 
						|
        'patterncontentunits': 'patternContentUnits', | 
						|
        'patterntransform': 'patternTransform', | 
						|
        'patternunits': 'patternUnits', | 
						|
        'pointsatx': 'pointsAtX', | 
						|
        'pointsaty': 'pointsAtY', | 
						|
        'pointsatz': 'pointsAtZ', | 
						|
        'preservealpha': 'preserveAlpha', | 
						|
        'preserveaspectratio': 'preserveAspectRatio', | 
						|
        'primitiveunits': 'primitiveUnits', | 
						|
        'refx': 'refX', | 
						|
        'refy': 'refY', | 
						|
        'repeatcount': 'repeatCount', | 
						|
        'repeatdur': 'repeatDur', | 
						|
        'requiredextensions': 'requiredExtensions', | 
						|
        'requiredfeatures': 'requiredFeatures', | 
						|
        'specularconstant': 'specularConstant', | 
						|
        'specularexponent': 'specularExponent', | 
						|
        'spreadmethod': 'spreadMethod', | 
						|
        'startoffset': 'startOffset', | 
						|
        'stddeviation': 'stdDeviation', | 
						|
        'stitchtiles': 'stitchTiles', | 
						|
        'surfacescale': 'surfaceScale', | 
						|
        'systemlanguage': 'systemLanguage', | 
						|
        'tablevalues': 'tableValues', | 
						|
        'targetx': 'targetX', | 
						|
        'targety': 'targetY', | 
						|
        'textlength': 'textLength', | 
						|
        'viewbox': 'viewBox', | 
						|
        'viewtarget': 'viewTarget', | 
						|
        'xchannelselector': 'xChannelSelector', | 
						|
        'ychannelselector': 'yChannelSelector', | 
						|
        'zoomandpan': 'zoomAndPan' | 
						|
    }, | 
						|
    XML_ATTRS_ADJUSTMENT_MAP = { | 
						|
        'xlink:actuate': {prefix: 'xlink', name: 'actuate', namespace: NS.XLINK}, | 
						|
        'xlink:arcrole': {prefix: 'xlink', name: 'arcrole', namespace: NS.XLINK}, | 
						|
        'xlink:href': {prefix: 'xlink', name: 'href', namespace: NS.XLINK}, | 
						|
        'xlink:role': {prefix: 'xlink', name: 'role', namespace: NS.XLINK}, | 
						|
        'xlink:show': {prefix: 'xlink', name: 'show', namespace: NS.XLINK}, | 
						|
        'xlink:title': {prefix: 'xlink', name: 'title', namespace: NS.XLINK}, | 
						|
        'xlink:type': {prefix: 'xlink', name: 'type', namespace: NS.XLINK}, | 
						|
        'xml:base': {prefix: 'xml', name: 'base', namespace: NS.XML}, | 
						|
        'xml:lang': {prefix: 'xml', name: 'lang', namespace: NS.XML}, | 
						|
        'xml:space': {prefix: 'xml', name: 'space', namespace: NS.XML}, | 
						|
        'xmlns': {prefix: '', name: 'xmlns', namespace: NS.XMLNS}, | 
						|
        'xmlns:xlink': {prefix: 'xmlns', name: 'xlink', namespace: NS.XMLNS} | 
						|
 | 
						|
    }; | 
						|
 | 
						|
//SVG tag names adjustment map | 
						|
var SVG_TAG_NAMES_ADJUSTMENT_MAP = exports.SVG_TAG_NAMES_ADJUSTMENT_MAP = { | 
						|
    'altglyph': 'altGlyph', | 
						|
    'altglyphdef': 'altGlyphDef', | 
						|
    'altglyphitem': 'altGlyphItem', | 
						|
    'animatecolor': 'animateColor', | 
						|
    'animatemotion': 'animateMotion', | 
						|
    'animatetransform': 'animateTransform', | 
						|
    'clippath': 'clipPath', | 
						|
    'feblend': 'feBlend', | 
						|
    'fecolormatrix': 'feColorMatrix', | 
						|
    'fecomponenttransfer': 'feComponentTransfer', | 
						|
    'fecomposite': 'feComposite', | 
						|
    'feconvolvematrix': 'feConvolveMatrix', | 
						|
    'fediffuselighting': 'feDiffuseLighting', | 
						|
    'fedisplacementmap': 'feDisplacementMap', | 
						|
    'fedistantlight': 'feDistantLight', | 
						|
    'feflood': 'feFlood', | 
						|
    'fefunca': 'feFuncA', | 
						|
    'fefuncb': 'feFuncB', | 
						|
    'fefuncg': 'feFuncG', | 
						|
    'fefuncr': 'feFuncR', | 
						|
    'fegaussianblur': 'feGaussianBlur', | 
						|
    'feimage': 'feImage', | 
						|
    'femerge': 'feMerge', | 
						|
    'femergenode': 'feMergeNode', | 
						|
    'femorphology': 'feMorphology', | 
						|
    'feoffset': 'feOffset', | 
						|
    'fepointlight': 'fePointLight', | 
						|
    'fespecularlighting': 'feSpecularLighting', | 
						|
    'fespotlight': 'feSpotLight', | 
						|
    'fetile': 'feTile', | 
						|
    'feturbulence': 'feTurbulence', | 
						|
    'foreignobject': 'foreignObject', | 
						|
    'glyphref': 'glyphRef', | 
						|
    'lineargradient': 'linearGradient', | 
						|
    'radialgradient': 'radialGradient', | 
						|
    'textpath': 'textPath' | 
						|
}; | 
						|
 | 
						|
//Tags that causes exit from foreign content | 
						|
var EXITS_FOREIGN_CONTENT = Object.create(null); | 
						|
 | 
						|
EXITS_FOREIGN_CONTENT[$.B] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.BIG] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.BLOCKQUOTE] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.BODY] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.BR] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.CENTER] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.CODE] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.DD] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.DIV] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.DL] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.DT] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.EM] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.EMBED] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.H1] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.H2] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.H3] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.H4] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.H5] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.H6] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.HEAD] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.HR] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.I] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.IMG] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.LI] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.LISTING] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.MENU] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.META] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.NOBR] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.OL] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.P] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.PRE] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.RUBY] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.S] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.SMALL] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.SPAN] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.STRONG] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.STRIKE] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.SUB] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.SUP] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.TABLE] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.TT] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.U] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.UL] = true; | 
						|
EXITS_FOREIGN_CONTENT[$.VAR] = true; | 
						|
 | 
						|
//Check exit from foreign content | 
						|
exports.causesExit = function (startTagToken) { | 
						|
    var tn = startTagToken.tagName; | 
						|
    var isFontWithAttrs = tn === $.FONT && (Tokenizer.getTokenAttr(startTagToken, ATTRS.COLOR) !== null || | 
						|
                                            Tokenizer.getTokenAttr(startTagToken, ATTRS.SIZE) !== null || | 
						|
                                            Tokenizer.getTokenAttr(startTagToken, ATTRS.FACE) !== null); | 
						|
 | 
						|
    return isFontWithAttrs ? true : EXITS_FOREIGN_CONTENT[tn]; | 
						|
}; | 
						|
 | 
						|
//Token adjustments | 
						|
exports.adjustTokenMathMLAttrs = function (token) { | 
						|
    for (var i = 0; i < token.attrs.length; i++) { | 
						|
        if (token.attrs[i].name === DEFINITION_URL_ATTR) { | 
						|
            token.attrs[i].name = ADJUSTED_DEFINITION_URL_ATTR; | 
						|
            break; | 
						|
        } | 
						|
    } | 
						|
}; | 
						|
 | 
						|
exports.adjustTokenSVGAttrs = function (token) { | 
						|
    for (var i = 0; i < token.attrs.length; i++) { | 
						|
        var adjustedAttrName = SVG_ATTRS_ADJUSTMENT_MAP[token.attrs[i].name]; | 
						|
 | 
						|
        if (adjustedAttrName) | 
						|
            token.attrs[i].name = adjustedAttrName; | 
						|
    } | 
						|
}; | 
						|
 | 
						|
exports.adjustTokenXMLAttrs = function (token) { | 
						|
    for (var i = 0; i < token.attrs.length; i++) { | 
						|
        var adjustedAttrEntry = XML_ATTRS_ADJUSTMENT_MAP[token.attrs[i].name]; | 
						|
 | 
						|
        if (adjustedAttrEntry) { | 
						|
            token.attrs[i].prefix = adjustedAttrEntry.prefix; | 
						|
            token.attrs[i].name = adjustedAttrEntry.name; | 
						|
            token.attrs[i].namespace = adjustedAttrEntry.namespace; | 
						|
        } | 
						|
    } | 
						|
}; | 
						|
 | 
						|
exports.adjustTokenSVGTagName = function (token) { | 
						|
    var adjustedTagName = SVG_TAG_NAMES_ADJUSTMENT_MAP[token.tagName]; | 
						|
 | 
						|
    if (adjustedTagName) | 
						|
        token.tagName = adjustedTagName; | 
						|
}; | 
						|
 | 
						|
//Integration points | 
						|
function isMathMLTextIntegrationPoint(tn, ns) { | 
						|
    return ns === NS.MATHML && (tn === $.MI || tn === $.MO || tn === $.MN || tn === $.MS || tn === $.MTEXT); | 
						|
} | 
						|
 | 
						|
function isHtmlIntegrationPoint(tn, ns, attrs) { | 
						|
    if (ns === NS.MATHML && tn === $.ANNOTATION_XML) { | 
						|
        for (var i = 0; i < attrs.length; i++) { | 
						|
            if (attrs[i].name === ATTRS.ENCODING) { | 
						|
                var value = attrs[i].value.toLowerCase(); | 
						|
 | 
						|
                return value === MIME_TYPES.TEXT_HTML || value === MIME_TYPES.APPLICATION_XML; | 
						|
            } | 
						|
        } | 
						|
    } | 
						|
 | 
						|
    return ns === NS.SVG && (tn === $.FOREIGN_OBJECT || tn === $.DESC || tn === $.TITLE); | 
						|
} | 
						|
 | 
						|
exports.isIntegrationPoint = function (tn, ns, attrs, foreignNS) { | 
						|
    if ((!foreignNS || foreignNS === NS.HTML) && isHtmlIntegrationPoint(tn, ns, attrs)) | 
						|
        return true; | 
						|
 | 
						|
    if ((!foreignNS || foreignNS === NS.MATHML) && isMathMLTextIntegrationPoint(tn, ns)) | 
						|
        return true; | 
						|
 | 
						|
    return false; | 
						|
};
 | 
						|
 |