Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(#7143): add eslint-plugin-no-sanitize and fix errors #7144

Merged
merged 12 commits into from
Oct 16, 2023
Merged
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ module.exports = {
'plugin:compat/recommended',
'plugin:vue/vue3-recommended',
'plugin:you-dont-need-lodash-underscore/compatible',
'plugin:prettier/recommended'
'plugin:prettier/recommended',
'plugin:no-unsanitized/DOM'
],
parser: 'vue-eslint-parser',
parserOptions: {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"eslint": "8.48.0",
"eslint-config-prettier": "9.0.0",
"eslint-plugin-compat": "4.2.0",
"eslint-plugin-no-unsanitized": "4.0.2",
"eslint-plugin-playwright": "0.12.0",
"eslint-plugin-prettier": "4.2.1",
"eslint-plugin-simple-import-sort": "10.0.0",
Expand Down
5 changes: 4 additions & 1 deletion src/plugins/flexibleLayout/components/FrameComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,11 @@ export default {
let originalClassName = this.dragGhost.classList[0];
this.dragGhost.className = '';
this.dragGhost.classList.add(originalClassName, iconClass);
this.dragGhost.textContent = '';
const span = document.createElement('span');
span.textContent = this.domainObject.name;
this.dragGhost.appendChild(span);

this.dragGhost.innerHTML = `<span>${this.domainObject.name}</span>`;
event.dataTransfer.setDragImage(this.dragGhost, 0, 0);
}

Expand Down
11 changes: 8 additions & 3 deletions src/plugins/plot/chart/MctChart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,6 @@ export default {
emits: ['chart-loaded', 'plot-reinitialize-canvas'],
data() {
return {
canvasTemplate:
'<canvas style="position: absolute; background: none; width: 100%; height: 100%;"></canvas>',
visibleLimitLabels: [],
visibleLimitLines: []
};
Expand Down Expand Up @@ -190,6 +188,10 @@ export default {
deep: true
}
},
created() {
this.canvasTemplate =
'<canvas style="position: absolute; background: none; width: 100%; height: 100%;"></canvas>';
},
mounted() {
eventHelpers.extend(this);
this.seriesModels = [];
Expand Down Expand Up @@ -488,7 +490,10 @@ export default {
// Have to throw away the old canvas elements and replace with new
// canvas elements in order to get new drawing contexts.
const div = document.createElement('div');
div.innerHTML = this.canvasTemplate + this.canvasTemplate;
div.innerHTML = `
ozyx marked this conversation as resolved.
Show resolved Hide resolved
<canvas style="position: absolute; background: none; width: 100%; height: 100%;"></canvas>
<canvas style="position: absolute; background: none; width: 100%; height: 100%;"></canvas>
`;
const mainCanvas = div.querySelectorAll('canvas')[1];
const overlayCanvas = div.querySelectorAll('canvas')[0];
this.canvas.parentNode.replaceChild(mainCanvas, this.canvas);
Expand Down
12 changes: 8 additions & 4 deletions src/plugins/summaryWidget/src/Condition.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@
const options = this.generateSelectOptions();

newInput = document.createElement('select');
newInput.innerHTML = options;
newInput.appendChild(options);

Check warning on line 217 in src/plugins/summaryWidget/src/Condition.js

View check run for this annotation

Codecov / codecov/patch

src/plugins/summaryWidget/src/Condition.js#L217

Added line #L217 was not covered by tests

emitChange = true;
} else {
Expand Down Expand Up @@ -244,12 +244,16 @@

Condition.prototype.generateSelectOptions = function () {
let telemetryMetadata = this.conditionManager.getTelemetryMetadata(this.config.object);
let options = '';
let fragment = document.createDocumentFragment();

Check warning on line 247 in src/plugins/summaryWidget/src/Condition.js

View check run for this annotation

Codecov / codecov/patch

src/plugins/summaryWidget/src/Condition.js#L247

Added line #L247 was not covered by tests

telemetryMetadata[this.config.key].enumerations.forEach((enumeration) => {
options += '<option value="' + enumeration.value + '">' + enumeration.string + '</option>';
const option = document.createElement('option');
option.value = enumeration.value;
option.textContent = enumeration.string;
fragment.appendChild(option);

Check warning on line 253 in src/plugins/summaryWidget/src/Condition.js

View check run for this annotation

Codecov / codecov/patch

src/plugins/summaryWidget/src/Condition.js#L250-L253

Added lines #L250 - L253 were not covered by tests
});

return options;
return fragment;

Check warning on line 256 in src/plugins/summaryWidget/src/Condition.js

View check run for this annotation

Codecov / codecov/patch

src/plugins/summaryWidget/src/Condition.js#L256

Added line #L256 was not covered by tests
};

return Condition;
Expand Down
11 changes: 6 additions & 5 deletions src/plugins/summaryWidget/src/Rule.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@
const ruleHeader = self.domElement
.querySelectorAll('.widget-rule-header')[0]
.cloneNode(true);
indicator.innerHTML = ruleHeader;
indicator.textContent = '';
indicator.appendChild(ruleHeader);

Check warning on line 171 in src/plugins/summaryWidget/src/Rule.js

View check run for this annotation

Codecov / codecov/patch

src/plugins/summaryWidget/src/Rule.js#L170-L171

Added lines #L170 - L171 were not covered by tests
});
self.widgetDnD.setDragImage(
self.domElement.querySelectorAll('.widget-rule-header')[0].cloneNode(true)
Expand Down Expand Up @@ -239,8 +240,8 @@
this.listenTo(this.toggleConfigButton, 'click', toggleConfig);
this.listenTo(this.trigger, 'change', onTriggerInput);

this.title.innerHTML = self.config.name;
this.description.innerHTML = self.config.description;
this.title.innerText = self.config.name;
this.description.innerText = self.config.description;
this.trigger.value = self.config.trigger;

this.listenTo(this.grippy, 'mousedown', onDragStart);
Expand Down Expand Up @@ -456,7 +457,7 @@
const lastOfType = self.conditionArea.querySelector('li:last-of-type');
lastOfType.parentNode.insertBefore($condition, lastOfType);
if (loopCnt > 0) {
$condition.querySelector('.t-condition-context').innerHTML = triggerContextStr + ' when';
$condition.querySelector('.t-condition-context').innerText = triggerContextStr + ' when';
}

loopCnt++;
Expand Down Expand Up @@ -528,7 +529,7 @@
}

description = description === '' ? this.config.description : description;
this.description.innerHTML = self.config.description;
this.description.innerText = self.config.description;
this.config.description = description;
};

Expand Down
3 changes: 2 additions & 1 deletion src/plugins/summaryWidget/src/SummaryWidget.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,10 @@ define([
SummaryWidget.prototype.updateWidget = function () {
const WIDGET_ICON_CLASS = 'c-sw__icon js-sw__icon';
const activeRule = this.rulesById[this.activeId];

this.applyStyle(this.domElement.querySelector('#widget'), activeRule.getProperty('style'));
this.domElement.querySelector('#widget').title = activeRule.getProperty('message');
this.domElement.querySelector('#widgetLabel').innerHTML = activeRule.getProperty('label');
this.domElement.querySelector('#widgetLabel').textContent = activeRule.getProperty('label');
this.domElement.querySelector('#widgetIcon').classList =
WIDGET_ICON_CLASS + ' ' + activeRule.getProperty('icon');
};
Expand Down
11 changes: 6 additions & 5 deletions src/plugins/summaryWidget/src/input/Palette.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ define([
self.setNullOption(this.nullOption);

self.items.forEach(function (item) {
const itemElement = `<div class = "c-palette__item ${item}" data-item = "${item}"></div>`;
const temp = document.createElement('div');
temp.innerHTML = itemElement;
self.itemElements[item] = temp.firstChild;
self.domElement.querySelector('.c-palette__items').appendChild(temp.firstChild);
const itemElement = document.createElement('div');
itemElement.className = 'c-palette__item ' + item;
itemElement.setAttribute('data-item', item);

self.itemElements[item] = itemElement;
self.domElement.querySelector('.c-palette__items').appendChild(itemElement);
});

self.domElement.querySelector('.c-menu').style.display = 'none';
Expand Down
92 changes: 58 additions & 34 deletions src/plugins/summaryWidget/src/views/SummaryWidgetView.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,60 @@
define(['./summary-widget.html', '@braintree/sanitize-url'], function (
summaryWidgetTemplate,
urlSanitizeLib
) {
const WIDGET_ICON_CLASS = 'c-sw__icon js-sw__icon';
import * as urlSanitizeLib from '@braintree/sanitize-url';

function SummaryWidgetView(domainObject, openmct) {
const WIDGET_ICON_CLASS = 'c-sw__icon js-sw__icon';

class SummaryWidgetView {
#createSummaryWidgetTemplate() {
const anchor = document.createElement('a');
anchor.classList.add(

Check warning on line 8 in src/plugins/summaryWidget/src/views/SummaryWidgetView.js

View check run for this annotation

Codecov / codecov/patch

src/plugins/summaryWidget/src/views/SummaryWidgetView.js#L7-L8

Added lines #L7 - L8 were not covered by tests
't-summary-widget',
'c-summary-widget',
'js-sw',
'u-links',
'u-fills-container'
);

const widgetIcon = document.createElement('div');
widgetIcon.id = 'widgetIcon';
widgetIcon.classList.add('c-sw__icon', 'js-sw__icon');
anchor.appendChild(widgetIcon);

Check warning on line 19 in src/plugins/summaryWidget/src/views/SummaryWidgetView.js

View check run for this annotation

Codecov / codecov/patch

src/plugins/summaryWidget/src/views/SummaryWidgetView.js#L16-L19

Added lines #L16 - L19 were not covered by tests

const widgetLabel = document.createElement('div');
widgetLabel.id = 'widgetLabel';
widgetLabel.classList.add('c-sw__label', 'js-sw__label');
widgetLabel.textContent = 'Loading...';
anchor.appendChild(widgetLabel);

Check warning on line 25 in src/plugins/summaryWidget/src/views/SummaryWidgetView.js

View check run for this annotation

Codecov / codecov/patch

src/plugins/summaryWidget/src/views/SummaryWidgetView.js#L21-L25

Added lines #L21 - L25 were not covered by tests

return anchor;

Check warning on line 27 in src/plugins/summaryWidget/src/views/SummaryWidgetView.js

View check run for this annotation

Codecov / codecov/patch

src/plugins/summaryWidget/src/views/SummaryWidgetView.js#L27

Added line #L27 was not covered by tests
}

constructor(domainObject, openmct) {
this.openmct = openmct;
this.domainObject = domainObject;
this.hasUpdated = false;
this.render = this.render.bind(this);
}

SummaryWidgetView.prototype.updateState = function (datum) {
updateState(datum) {
this.hasUpdated = true;
this.widget.style.color = datum.textColor;
this.widget.style.backgroundColor = datum.backgroundColor;
this.widget.style.borderColor = datum.borderColor;
this.widget.title = datum.message;
this.label.title = datum.message;
this.label.innerHTML = datum.ruleLabel;
this.label.textContent = datum.ruleLabel;

Check warning on line 44 in src/plugins/summaryWidget/src/views/SummaryWidgetView.js

View check run for this annotation

Codecov / codecov/patch

src/plugins/summaryWidget/src/views/SummaryWidgetView.js#L44

Added line #L44 was not covered by tests
this.icon.className = WIDGET_ICON_CLASS + ' ' + datum.icon;
};
}

SummaryWidgetView.prototype.render = function () {
render() {
if (this.unsubscribe) {
this.unsubscribe();
}

this.hasUpdated = false;

this.container.innerHTML = summaryWidgetTemplate;
const anchor = this.#createSummaryWidgetTemplate();
this.container.appendChild(anchor);

Check warning on line 56 in src/plugins/summaryWidget/src/views/SummaryWidgetView.js

View check run for this annotation

Codecov / codecov/patch

src/plugins/summaryWidget/src/views/SummaryWidgetView.js#L55-L56

Added lines #L55 - L56 were not covered by tests

this.widget = this.container.querySelector('a');
this.icon = this.container.querySelector('#widgetIcon');
this.label = this.container.querySelector('.js-sw__label');
Expand All @@ -49,33 +74,32 @@

const renderTracker = {};
this.renderTracker = renderTracker;

this.openmct.telemetry
.request(this.domainObject, {
strategy: 'latest',
size: 1
})
.then(
function (results) {
if (
this.destroyed ||
this.hasUpdated ||
this.renderTracker !== renderTracker ||
results.length === 0
) {
return;
}

this.updateState(results[results.length - 1]);
}.bind(this)
);
.then((results) => {
if (

Check warning on line 84 in src/plugins/summaryWidget/src/views/SummaryWidgetView.js

View check run for this annotation

Codecov / codecov/patch

src/plugins/summaryWidget/src/views/SummaryWidgetView.js#L84

Added line #L84 was not covered by tests
this.destroyed ||
this.hasUpdated ||
this.renderTracker !== renderTracker ||
results.length === 0
) {
return;

Check warning on line 90 in src/plugins/summaryWidget/src/views/SummaryWidgetView.js

View check run for this annotation

Codecov / codecov/patch

src/plugins/summaryWidget/src/views/SummaryWidgetView.js#L90

Added line #L90 was not covered by tests
}

this.updateState(results[results.length - 1]);

Check warning on line 93 in src/plugins/summaryWidget/src/views/SummaryWidgetView.js

View check run for this annotation

Codecov / codecov/patch

src/plugins/summaryWidget/src/views/SummaryWidgetView.js#L93

Added line #L93 was not covered by tests
});

this.unsubscribe = this.openmct.telemetry.subscribe(
this.domainObject,
this.updateState.bind(this)
);
};
}

SummaryWidgetView.prototype.show = function (container) {
show(container) {
this.container = container;
this.render();
this.removeMutationListener = this.openmct.objects.observe(
Expand All @@ -84,14 +108,14 @@
this.onMutation.bind(this)
);
this.openmct.time.on('timeSystem', this.render);
};
}

SummaryWidgetView.prototype.onMutation = function (domainObject) {
onMutation(domainObject) {
this.domainObject = domainObject;
this.render();
};
}

SummaryWidgetView.prototype.destroy = function (container) {
destroy() {
this.unsubscribe();
this.removeMutationListener();
this.openmct.time.off('timeSystem', this.render);
Expand All @@ -100,7 +124,7 @@
delete this.label;
delete this.openmct;
delete this.domainObject;
};
}
}

return SummaryWidgetView;
});
export default SummaryWidgetView;
4 changes: 0 additions & 4 deletions src/plugins/summaryWidget/src/views/summary-widget.html

This file was deleted.

15 changes: 12 additions & 3 deletions src/utils/template/templateHelpers.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
export function convertTemplateToHTML(templateString) {
const template = document.createElement('template');
template.innerHTML = templateString;
const parser = new DOMParser();
const doc = parser.parseFromString(templateString, 'text/html');

return template.content.cloneNode(true).children;
// Create a document fragment to hold the parsed content
const fragment = document.createDocumentFragment();

// Append nodes from the parsed content to the fragment
while (doc.body.firstChild) {
fragment.appendChild(doc.body.firstChild);
}

// Convert children of the fragment to an array and return
return Array.from(fragment.children);
}

export function toggleClass(element, className) {
Expand Down