dynatrace-cordova-outsystems-plugin
Version:
This plugin gives you the ability to use the Dynatrace instrumentation in your hybrid application (Cordova, Ionic, ..). It uses the Mobile Agent, the JavaScript Agent and the Javascript Bridge. The Mobile Agent will give you all device specific values con
266 lines (242 loc) • 8.16 kB
JavaScript
;
const Tokenizer = require('../tokenizer');
const HTML = require('./html');
//Aliases
const $ = HTML.TAG_NAMES;
const NS = HTML.NAMESPACES;
const ATTRS = HTML.ATTRS;
//MIME types
const MIME_TYPES = {
TEXT_HTML: 'text/html',
APPLICATION_XML: 'application/xhtml+xml'
};
//Attributes
const DEFINITION_URL_ATTR = 'definitionurl';
const ADJUSTED_DEFINITION_URL_ATTR = 'definitionURL';
const 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'
};
const 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
const 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
const EXITS_FOREIGN_CONTENT = {
[$.B]: true,
[$.BIG]: true,
[$.BLOCKQUOTE]: true,
[$.BODY]: true,
[$.BR]: true,
[$.CENTER]: true,
[$.CODE]: true,
[$.DD]: true,
[$.DIV]: true,
[$.DL]: true,
[$.DT]: true,
[$.EM]: true,
[$.EMBED]: true,
[$.H1]: true,
[$.H2]: true,
[$.H3]: true,
[$.H4]: true,
[$.H5]: true,
[$.H6]: true,
[$.HEAD]: true,
[$.HR]: true,
[$.I]: true,
[$.IMG]: true,
[$.LI]: true,
[$.LISTING]: true,
[$.MENU]: true,
[$.META]: true,
[$.NOBR]: true,
[$.OL]: true,
[$.P]: true,
[$.PRE]: true,
[$.RUBY]: true,
[$.S]: true,
[$.SMALL]: true,
[$.SPAN]: true,
[$.STRONG]: true,
[$.STRIKE]: true,
[$.SUB]: true,
[$.SUP]: true,
[$.TABLE]: true,
[$.TT]: true,
[$.U]: true,
[$.UL]: true,
[$.VAR]: true
};
//Check exit from foreign content
exports.causesExit = function(startTagToken) {
const tn = startTagToken.tagName;
const 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 (let 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 (let i = 0; i < token.attrs.length; i++) {
const adjustedAttrName = SVG_ATTRS_ADJUSTMENT_MAP[token.attrs[i].name];
if (adjustedAttrName) {
token.attrs[i].name = adjustedAttrName;
}
}
};
exports.adjustTokenXMLAttrs = function(token) {
for (let i = 0; i < token.attrs.length; i++) {
const 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) {
const 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 (let i = 0; i < attrs.length; i++) {
if (attrs[i].name === ATTRS.ENCODING) {
const 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;
};