UNPKG

maestro-roku-bsc-plugin

Version:

Visual studio plugin for maestro brightscript development

173 lines 8.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.XMLTag = void 0; const Binding_1 = require("./Binding"); const BindingType_1 = require("./BindingType"); const Diagnostics_1 = require("../utils/Diagnostics"); class XMLTag { constructor(xmlTag, file, isTopTag) { if (!xmlTag) { (0, Diagnostics_1.addXMLTagErrorCorruptXMLElement)(file, ''); } this.file = file; this.isTopTag = isTopTag; this.bindings = this.getBindings(xmlTag); } getBindings(xmlElement) { // eslint-disable-next-line prefer-regex-literals const staticRegex = new RegExp('^{(\\{\\:|\\{\\=)+(.*)(\\})+\\}$', 'i'); // eslint-disable-next-line prefer-regex-literals const regex = new RegExp('^\\{([\\(\\{\\[])+(.*)([\\}\\)\\]])+\\}$', 'i'); this.id = xmlElement.id; const bindings = []; for (const attribute of xmlElement.attributes) { let key = attribute.key.text; if (key.toLowerCase() !== 'id') { let value = attribute.value.text; let matches = staticRegex.exec(value); matches = matches || regex.exec(value); const bindingText = matches && matches.length > 2 ? matches[2] : null; const bindingStartType = matches && matches.length > 1 ? matches[1] : null; const bindingEndType = matches && matches.length > 3 ? matches[3] : null; let mode = this.getBindingMode(bindingStartType, bindingEndType); if (bindingText) { if (mode === BindingType_1.BindingType.invalid && bindingStartType) { (0, Diagnostics_1.addXMLTagErrorCouldMissingEndBrackets)(this.file, value, attribute.value.range); continue; } const binding = new Binding_1.default(this.file); binding.nodeId = this.isTopTag ? 'top' : this.id; binding.nodeField = this.isTopTag ? this.id : key; binding.isTopBinding = this.isTopTag; binding.attribute = attribute; if (binding.properties.type === BindingType_1.BindingType.invalid) { binding.properties.type = mode; } binding.range = attribute.range; if (mode === BindingType_1.BindingType.code) { binding.rawValueText = value.substring(3, value.length - 2); } else if (mode === BindingType_1.BindingType.twoWay) { //is it a Binding and sub binding (e.g. [{vmField}|vmFunc()]) let parts = /(.*)\| *(.*)/.exec(bindingText); if (parts && parts.length > 2) { binding.createBinding(true); binding.createBinding(false); this.parseSubBindingText(parts[1], binding.getBinding, binding.properties.type); this.parseSubBindingText(parts[2], binding.setBinding, binding.properties.type); if (!binding.getBinding.isValid) { binding.isValid = false; binding.errorMessage = binding.getBinding.errorMessage; } else if (!binding.setBinding.isValid) { binding.isValid = false; binding.errorMessage = binding.setBinding.errorMessage; } binding.rawValueText = value; } else { this.parseBindingText(bindingText, binding, value, binding.properties.type); binding.rawValueText = value; } } else { this.parseBindingText(bindingText, binding, value, binding.properties.type); } binding.tagText = value; if (!binding.errorMessage) { binding.validate(); } bindings.push(binding); if (!binding.isValid) { (0, Diagnostics_1.addXMLTagErrorCouldNotParseBinding)(this.file, value, binding.errorMessage, binding.range); } } else { // eslint-disable-next-line prefer-regex-literals const startRegex = new RegExp('^\\{([\\(\\{\\[])', 'i'); if (startRegex.test(value)) { (0, Diagnostics_1.addXMLTagErrorCouldMissingEndBrackets)(this.file, value, attribute.range); } } } } for (let b of bindings) { if (this.isTopTag) { xmlElement.getAttribute('value').value.text = ''; } else { // eslint-disable-next-line @typescript-eslint/no-unsafe-argument xmlElement.setAttribute(b.nodeField.toLowerCase(), undefined); } } this.hasBindings = bindings.length > 0; return bindings; } parseSubBindingText(text, binding, bindingType) { const parts = text.split(':'); for (let i = 0; i < parts.length; i++) { this.parseBindingPart(i, parts[i].replace(/\s/g, ''), binding, text, binding.range, bindingType); } binding.rawValueText = text; } parseBindingText(text, binding, tagText, bindingType) { const parts = text.split(':'); for (let i = 0; i < parts.length; i++) { this.parseBindingPart(i, parts[i].replace(/\s/g, ''), binding, tagText, binding.range, bindingType); } binding.rawValueText = tagText; } parseBindingPart(index, partText, binding, tagText, range, bindingType) { if (index === 0) { binding.parseObserveField(partText); if (bindingType === BindingType_1.BindingType.oneWayTarget && binding.properties.sendMode === BindingType_1.BindingSendMode.badlyFormed) { binding.isValid = false; binding.errorMessage = `Binding observer ${tagText} is configured as a function binding; but with an incorrect signature. Either use a field as the target of this binding, or indicate the function call signature: e.g. (), (value), (node), or (value, node).`; } } else if (partText.toLowerCase().includes('transform=')) { //transform function let transformFunction = partText.substring(10); if (transformFunction.trim()) { binding.properties.transformFunction = transformFunction; } else { (0, Diagnostics_1.addXMLTagErrorCouldNotParseBindingTransformFunctionForField)(this.file, partText, tagText, range); } } else if (partText.toLowerCase().trim() === 'eager') { binding.properties.fireTiming = 'eager'; } else if (partText.toLowerCase().trim() === 'lazy') { binding.properties.fireTiming = 'lazy'; } else if (partText.toLowerCase().trim() === 'once') { binding.properties.isFiringOnce = true; } else { (0, Diagnostics_1.addXMLTagErrorCouldNotParseIsFiringOnceForField)(this.file, partText, binding); } } getBindingMode(bindingStartType, bindingEndType) { if (bindingStartType === '{' && bindingEndType === '}') { return BindingType_1.BindingType.oneWaySource; } else if (bindingStartType === '(' && bindingEndType === ')') { return BindingType_1.BindingType.oneWayTarget; } else if (bindingStartType === '[' && bindingEndType === ']') { return BindingType_1.BindingType.twoWay; } else if (bindingStartType === '{:' && bindingEndType === '}') { return BindingType_1.BindingType.static; } else if (bindingStartType === '{=' && bindingEndType === '}') { return BindingType_1.BindingType.code; } else { return BindingType_1.BindingType.invalid; } } } exports.XMLTag = XMLTag; //# sourceMappingURL=XMLTag.js.map