mirror of
https://github.com/nasa/openmct.git
synced 2024-12-25 07:41:06 +00:00
Provide visibility based rendering as part of the view api (#7241) * first draft * in preview mode, just show it * fix unit tests
This commit is contained in:
parent
15ee8303e4
commit
f0dcf2ba21
@ -34,7 +34,7 @@ export default class LADTableView {
|
|||||||
this._destroy = null;
|
this._destroy = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
show(element) {
|
show(element, isEditing, { renderWhenVisible }) {
|
||||||
let ladTableConfiguration = new LADTableConfiguration(this.domainObject, this.openmct);
|
let ladTableConfiguration = new LADTableConfiguration(this.domainObject, this.openmct);
|
||||||
|
|
||||||
const { vNode, destroy } = mount(
|
const { vNode, destroy } = mount(
|
||||||
@ -46,7 +46,8 @@ export default class LADTableView {
|
|||||||
provide: {
|
provide: {
|
||||||
openmct: this.openmct,
|
openmct: this.openmct,
|
||||||
currentView: this,
|
currentView: this,
|
||||||
ladTableConfiguration
|
ladTableConfiguration,
|
||||||
|
renderWhenVisible
|
||||||
},
|
},
|
||||||
data: () => {
|
data: () => {
|
||||||
return {
|
return {
|
||||||
|
@ -54,12 +54,11 @@ const BLANK_VALUE = '---';
|
|||||||
import identifierToString from '/src/tools/url';
|
import identifierToString from '/src/tools/url';
|
||||||
import PreviewAction from '@/ui/preview/PreviewAction.js';
|
import PreviewAction from '@/ui/preview/PreviewAction.js';
|
||||||
|
|
||||||
import NicelyCalled from '../../../api/nice/NicelyCalled';
|
|
||||||
import tooltipHelpers from '../../../api/tooltips/tooltipMixins';
|
import tooltipHelpers from '../../../api/tooltips/tooltipMixins';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [tooltipHelpers],
|
mixins: [tooltipHelpers],
|
||||||
inject: ['openmct', 'currentView'],
|
inject: ['openmct', 'currentView', 'renderWhenVisible'],
|
||||||
props: {
|
props: {
|
||||||
domainObject: {
|
domainObject: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -190,7 +189,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
this.nicelyCalled = new NicelyCalled(this.$refs.tableRow);
|
|
||||||
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
|
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
|
||||||
this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
|
this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
|
||||||
this.keyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
this.keyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
||||||
@ -239,12 +237,11 @@ export default {
|
|||||||
this.previewAction.off('isVisible', this.togglePreviewState);
|
this.previewAction.off('isVisible', this.togglePreviewState);
|
||||||
|
|
||||||
this.telemetryCollection.destroy();
|
this.telemetryCollection.destroy();
|
||||||
this.nicelyCalled.destroy();
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateView() {
|
updateView() {
|
||||||
if (!this.updatingView) {
|
if (!this.updatingView) {
|
||||||
this.updatingView = this.nicelyCalled.execute(() => {
|
this.updatingView = this.renderWhenVisible(() => {
|
||||||
this.timestamp = this.getParsedTimestamp(this.latestDatum);
|
this.timestamp = this.getParsedTimestamp(this.latestDatum);
|
||||||
this.datum = this.latestDatum;
|
this.datum = this.latestDatum;
|
||||||
this.updatingView = false;
|
this.updatingView = false;
|
||||||
|
@ -24,6 +24,7 @@ import {
|
|||||||
getLatestTelemetry,
|
getLatestTelemetry,
|
||||||
getMockObjects,
|
getMockObjects,
|
||||||
getMockTelemetry,
|
getMockTelemetry,
|
||||||
|
renderWhenVisible,
|
||||||
resetApplicationState,
|
resetApplicationState,
|
||||||
spyOnBuiltins
|
spyOnBuiltins
|
||||||
} from 'utils/testing';
|
} from 'utils/testing';
|
||||||
@ -225,7 +226,7 @@ describe('The LAD Table', () => {
|
|||||||
(viewProvider) => viewProvider.key === ladTableKey
|
(viewProvider) => viewProvider.key === ladTableKey
|
||||||
);
|
);
|
||||||
ladTableView = ladTableViewProvider.view(mockObj.ladTable, [mockObj.ladTable]);
|
ladTableView = ladTableViewProvider.view(mockObj.ladTable, [mockObj.ladTable]);
|
||||||
ladTableView.show(child, true);
|
ladTableView.show(child, true, { renderWhenVisible });
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
telemetryRequestPromise,
|
telemetryRequestPromise,
|
||||||
|
@ -73,14 +73,18 @@ import {
|
|||||||
} from '@/plugins/notebook/utils/notebook-storage.js';
|
} from '@/plugins/notebook/utils/notebook-storage.js';
|
||||||
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
||||||
|
|
||||||
import NicelyCalled from '../../../api/nice/NicelyCalled';
|
|
||||||
import tooltipHelpers from '../../../api/tooltips/tooltipMixins';
|
import tooltipHelpers from '../../../api/tooltips/tooltipMixins';
|
||||||
import conditionalStylesMixin from '../mixins/objectStyles-mixin';
|
import conditionalStylesMixin from '../mixins/objectStyles-mixin';
|
||||||
import LayoutFrame from './LayoutFrame.vue';
|
import LayoutFrame from './LayoutFrame.vue';
|
||||||
|
|
||||||
const DEFAULT_TELEMETRY_DIMENSIONS = [10, 5];
|
const DEFAULT_TELEMETRY_DIMENSIONS = [10, 5];
|
||||||
const DEFAULT_POSITION = [1, 1];
|
const DEFAULT_POSITION = [1, 1];
|
||||||
const CONTEXT_MENU_ACTIONS = ['copyToClipboard', 'copyToNotebook', 'viewHistoricalData'];
|
const CONTEXT_MENU_ACTIONS = [
|
||||||
|
'copyToClipboard',
|
||||||
|
'copyToNotebook',
|
||||||
|
'viewHistoricalData',
|
||||||
|
'renderWhenVisible'
|
||||||
|
];
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
makeDefinition(openmct, gridSize, domainObject, position) {
|
makeDefinition(openmct, gridSize, domainObject, position) {
|
||||||
@ -106,7 +110,7 @@ export default {
|
|||||||
LayoutFrame
|
LayoutFrame
|
||||||
},
|
},
|
||||||
mixins: [conditionalStylesMixin, stalenessMixin, tooltipHelpers],
|
mixins: [conditionalStylesMixin, stalenessMixin, tooltipHelpers],
|
||||||
inject: ['openmct', 'objectPath', 'currentView'],
|
inject: ['openmct', 'objectPath', 'currentView', 'renderWhenVisible'],
|
||||||
props: {
|
props: {
|
||||||
item: {
|
item: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -274,7 +278,6 @@ export default {
|
|||||||
}
|
}
|
||||||
this.setObject(foundObject);
|
this.setObject(foundObject);
|
||||||
await this.$nextTick();
|
await this.$nextTick();
|
||||||
this.nicelyCalled = new NicelyCalled(this.$refs.telemetryViewWrapper);
|
|
||||||
},
|
},
|
||||||
formattedValueForCopy() {
|
formattedValueForCopy() {
|
||||||
const timeFormatterKey = this.openmct.time.timeSystem().key;
|
const timeFormatterKey = this.openmct.time.timeSystem().key;
|
||||||
@ -291,7 +294,7 @@ export default {
|
|||||||
},
|
},
|
||||||
updateView() {
|
updateView() {
|
||||||
if (!this.updatingView) {
|
if (!this.updatingView) {
|
||||||
this.updatingView = this.nicelyCalled.execute(() => {
|
this.updatingView = this.renderWhenVisible(() => {
|
||||||
this.datum = this.latestDatum;
|
this.datum = this.latestDatum;
|
||||||
this.updatingView = false;
|
this.updatingView = false;
|
||||||
});
|
});
|
||||||
|
@ -39,7 +39,7 @@ class DisplayLayoutView {
|
|||||||
this.component = null;
|
this.component = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
show(container, isEditing) {
|
show(container, isEditing, { renderWhenVisible }) {
|
||||||
const { vNode, destroy } = mount(
|
const { vNode, destroy } = mount(
|
||||||
{
|
{
|
||||||
el: container,
|
el: container,
|
||||||
@ -50,7 +50,8 @@ class DisplayLayoutView {
|
|||||||
openmct: this.openmct,
|
openmct: this.openmct,
|
||||||
objectPath: this.objectPath,
|
objectPath: this.objectPath,
|
||||||
options: this.options,
|
options: this.options,
|
||||||
currentView: this
|
currentView: this,
|
||||||
|
renderWhenVisible
|
||||||
},
|
},
|
||||||
data: () => {
|
data: () => {
|
||||||
return {
|
return {
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
import { createOpenMct, resetApplicationState } from 'utils/testing';
|
import { createOpenMct, renderWhenVisible, resetApplicationState } from 'utils/testing';
|
||||||
import { nextTick } from 'vue';
|
import { nextTick } from 'vue';
|
||||||
|
|
||||||
import DisplayLayoutPlugin from './plugin';
|
import DisplayLayoutPlugin from './plugin';
|
||||||
@ -114,7 +114,7 @@ describe('the plugin', function () {
|
|||||||
let error;
|
let error;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
view.show(child, false);
|
view.show(child, false, { renderWhenVisible });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = e;
|
error = e;
|
||||||
}
|
}
|
||||||
@ -161,7 +161,7 @@ describe('the plugin', function () {
|
|||||||
(viewProvider) => viewProvider.key === 'layout.view'
|
(viewProvider) => viewProvider.key === 'layout.view'
|
||||||
);
|
);
|
||||||
const view = displayLayoutViewProvider.view(displayLayoutItem, displayLayoutItem);
|
const view = displayLayoutViewProvider.view(displayLayoutItem, displayLayoutItem);
|
||||||
view.show(child, false);
|
view.show(child, false, { renderWhenVisible });
|
||||||
|
|
||||||
nextTick(done);
|
nextTick(done);
|
||||||
});
|
});
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
import { createOpenMct, resetApplicationState } from 'utils/testing';
|
import { createOpenMct, renderWhenVisible, resetApplicationState } from 'utils/testing';
|
||||||
import { nextTick } from 'vue';
|
import { nextTick } from 'vue';
|
||||||
|
|
||||||
let gaugeDomainObject = {
|
let gaugeDomainObject = {
|
||||||
@ -172,7 +172,7 @@ describe('Gauge plugin', () => {
|
|||||||
return openmct.objects.getMutable(gaugeViewObject.identifier).then((mutableObject) => {
|
return openmct.objects.getMutable(gaugeViewObject.identifier).then((mutableObject) => {
|
||||||
mutablegaugeObject = mutableObject;
|
mutablegaugeObject = mutableObject;
|
||||||
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
|
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
|
||||||
gaugeView.show(child);
|
gaugeView.show(child, false, { renderWhenVisible });
|
||||||
|
|
||||||
return nextTick();
|
return nextTick();
|
||||||
});
|
});
|
||||||
@ -314,7 +314,7 @@ describe('Gauge plugin', () => {
|
|||||||
return openmct.objects.getMutable(gaugeViewObject.identifier).then((mutableObject) => {
|
return openmct.objects.getMutable(gaugeViewObject.identifier).then((mutableObject) => {
|
||||||
mutablegaugeObject = mutableObject;
|
mutablegaugeObject = mutableObject;
|
||||||
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
|
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
|
||||||
gaugeView.show(child);
|
gaugeView.show(child, false, { renderWhenVisible });
|
||||||
|
|
||||||
return nextTick();
|
return nextTick();
|
||||||
});
|
});
|
||||||
@ -456,7 +456,7 @@ describe('Gauge plugin', () => {
|
|||||||
return openmct.objects.getMutable(gaugeViewObject.identifier).then((mutableObject) => {
|
return openmct.objects.getMutable(gaugeViewObject.identifier).then((mutableObject) => {
|
||||||
mutablegaugeObject = mutableObject;
|
mutablegaugeObject = mutableObject;
|
||||||
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
|
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
|
||||||
gaugeView.show(child);
|
gaugeView.show(child, false, { renderWhenVisible });
|
||||||
|
|
||||||
return nextTick();
|
return nextTick();
|
||||||
});
|
});
|
||||||
@ -560,7 +560,7 @@ describe('Gauge plugin', () => {
|
|||||||
mutablegaugeObject = mutableObject;
|
mutablegaugeObject = mutableObject;
|
||||||
|
|
||||||
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
|
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
|
||||||
gaugeView.show(child);
|
gaugeView.show(child, false, { renderWhenVisible });
|
||||||
|
|
||||||
return nextTick();
|
return nextTick();
|
||||||
});
|
});
|
||||||
@ -643,7 +643,7 @@ describe('Gauge plugin', () => {
|
|||||||
mutablegaugeObject = mutableObject;
|
mutablegaugeObject = mutableObject;
|
||||||
|
|
||||||
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
|
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
|
||||||
gaugeView.show(child);
|
gaugeView.show(child, false, { renderWhenVisible });
|
||||||
|
|
||||||
return nextTick();
|
return nextTick();
|
||||||
});
|
});
|
||||||
@ -771,7 +771,7 @@ describe('Gauge plugin', () => {
|
|||||||
return openmct.objects.getMutable(gaugeViewObject.identifier).then((mutableObject) => {
|
return openmct.objects.getMutable(gaugeViewObject.identifier).then((mutableObject) => {
|
||||||
mutablegaugeObject = mutableObject;
|
mutablegaugeObject = mutableObject;
|
||||||
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
|
gaugeView = gaugeViewProvider.view(mutablegaugeObject, [mutablegaugeObject]);
|
||||||
gaugeView.show(child);
|
gaugeView.show(child, false, { renderWhenVisible });
|
||||||
|
|
||||||
return nextTick();
|
return nextTick();
|
||||||
});
|
});
|
||||||
|
@ -41,7 +41,7 @@ export default function GaugeViewProvider(openmct) {
|
|||||||
let _destroy = null;
|
let _destroy = null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
show: function (element) {
|
show: function (element, isEditing, { renderWhenVisible }) {
|
||||||
const { destroy } = mount(
|
const { destroy } = mount(
|
||||||
{
|
{
|
||||||
el: element,
|
el: element,
|
||||||
@ -51,7 +51,8 @@ export default function GaugeViewProvider(openmct) {
|
|||||||
provide: {
|
provide: {
|
||||||
openmct,
|
openmct,
|
||||||
domainObject,
|
domainObject,
|
||||||
composition: openmct.composition.get(domainObject)
|
composition: openmct.composition.get(domainObject),
|
||||||
|
renderWhenVisible
|
||||||
},
|
},
|
||||||
template: '<gauge-component></gauge-component>'
|
template: '<gauge-component></gauge-component>'
|
||||||
},
|
},
|
||||||
|
@ -336,7 +336,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
||||||
|
|
||||||
import NicelyCalled from '../../../api/nice/NicelyCalled';
|
|
||||||
import tooltipHelpers from '../../../api/tooltips/tooltipMixins';
|
import tooltipHelpers from '../../../api/tooltips/tooltipMixins';
|
||||||
import { DIAL_VALUE_DEG_OFFSET, getLimitDegree } from '../gauge-limit-util';
|
import { DIAL_VALUE_DEG_OFFSET, getLimitDegree } from '../gauge-limit-util';
|
||||||
|
|
||||||
@ -345,7 +344,7 @@ const DEFAULT_CURRENT_VALUE = '--';
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [stalenessMixin, tooltipHelpers],
|
mixins: [stalenessMixin, tooltipHelpers],
|
||||||
inject: ['openmct', 'domainObject', 'composition'],
|
inject: ['openmct', 'domainObject', 'composition', 'renderWhenVisible'],
|
||||||
data() {
|
data() {
|
||||||
let gaugeController = this.domainObject.configuration.gaugeController;
|
let gaugeController = this.domainObject.configuration.gaugeController;
|
||||||
|
|
||||||
@ -539,7 +538,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.nicelyCalled = new NicelyCalled(this.$refs.gaugeWrapper);
|
|
||||||
this.composition.on('add', this.addedToComposition);
|
this.composition.on('add', this.addedToComposition);
|
||||||
this.composition.on('remove', this.removeTelemetryObject);
|
this.composition.on('remove', this.removeTelemetryObject);
|
||||||
|
|
||||||
@ -563,8 +561,6 @@ export default {
|
|||||||
|
|
||||||
this.openmct.time.off('bounds', this.refreshData);
|
this.openmct.time.off('bounds', this.refreshData);
|
||||||
this.openmct.time.off('timeSystem', this.setTimeSystem);
|
this.openmct.time.off('timeSystem', this.setTimeSystem);
|
||||||
|
|
||||||
this.nicelyCalled.destroy();
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getLimitDegree: getLimitDegree,
|
getLimitDegree: getLimitDegree,
|
||||||
@ -737,7 +733,7 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isRendering = this.nicelyCalled.execute(() => {
|
this.isRendering = this.renderWhenVisible(() => {
|
||||||
this.isRendering = false;
|
this.isRendering = false;
|
||||||
|
|
||||||
this.curVal = this.round(this.formats[this.valueKey].format(this.datum), this.precision);
|
this.curVal = this.round(this.formats[this.valueKey].format(this.datum), this.precision);
|
||||||
|
@ -633,13 +633,22 @@ describe('The Imagery View Layouts', () => {
|
|||||||
imageWrapper[2].dispatchEvent(mouseDownEvent);
|
imageWrapper[2].dispatchEvent(mouseDownEvent);
|
||||||
await nextTick();
|
await nextTick();
|
||||||
const timestamp = imageWrapper[2].id.replace('wrapper-', '');
|
const timestamp = imageWrapper[2].id.replace('wrapper-', '');
|
||||||
expect(componentView.previewAction.invoke).toHaveBeenCalledWith(
|
const mockInvoke = componentView.previewAction.invoke;
|
||||||
[componentView.objectPath[0]],
|
// Make sure the function was called
|
||||||
{
|
expect(mockInvoke).toHaveBeenCalled();
|
||||||
timestamp: Number(timestamp),
|
|
||||||
objectPath: componentView.objectPath
|
// Get the arguments of the first call
|
||||||
}
|
const firstArg = mockInvoke.calls.mostRecent().args[0];
|
||||||
);
|
const secondArg = mockInvoke.calls.mostRecent().args[1];
|
||||||
|
|
||||||
|
// Compare the first argument
|
||||||
|
expect(firstArg).toEqual([componentView.objectPath[0]]);
|
||||||
|
|
||||||
|
// Compare the "timestamp" property of the second argument
|
||||||
|
expect(secondArg.timestamp).toEqual(Number(timestamp));
|
||||||
|
|
||||||
|
// Compare the "objectPath" property of the second argument
|
||||||
|
expect(secondArg.objectPath).toEqual(componentView.objectPath);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove images when clock advances', async () => {
|
it('should remove images when clock advances', async () => {
|
||||||
|
@ -198,7 +198,7 @@ export default {
|
|||||||
MctTicks,
|
MctTicks,
|
||||||
MctChart
|
MctChart
|
||||||
},
|
},
|
||||||
inject: ['openmct', 'domainObject', 'path'],
|
inject: ['openmct', 'domainObject', 'path', 'renderWhenVisible'],
|
||||||
props: {
|
props: {
|
||||||
options: {
|
options: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -65,7 +65,7 @@ export default function PlotViewProvider(openmct) {
|
|||||||
let component = null;
|
let component = null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
show: function (element) {
|
show: function (element, isEditing, { renderWhenVisible }) {
|
||||||
let isCompact = isCompactView(objectPath);
|
let isCompact = isCompactView(objectPath);
|
||||||
const { vNode, destroy } = mount(
|
const { vNode, destroy } = mount(
|
||||||
{
|
{
|
||||||
@ -76,7 +76,8 @@ export default function PlotViewProvider(openmct) {
|
|||||||
provide: {
|
provide: {
|
||||||
openmct,
|
openmct,
|
||||||
domainObject,
|
domainObject,
|
||||||
path: objectPath
|
path: objectPath,
|
||||||
|
renderWhenVisible
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -45,7 +45,6 @@
|
|||||||
import mount from 'utils/mount';
|
import mount from 'utils/mount';
|
||||||
import { toRaw } from 'vue';
|
import { toRaw } from 'vue';
|
||||||
|
|
||||||
import NicelyCalled from '../../../api/nice/NicelyCalled';
|
|
||||||
import configStore from '../configuration/ConfigStore';
|
import configStore from '../configuration/ConfigStore';
|
||||||
import PlotConfigurationModel from '../configuration/PlotConfigurationModel';
|
import PlotConfigurationModel from '../configuration/PlotConfigurationModel';
|
||||||
import { DrawLoader } from '../draw/DrawLoader';
|
import { DrawLoader } from '../draw/DrawLoader';
|
||||||
@ -100,7 +99,7 @@ const HANDLED_ATTRIBUTES = {
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { LimitLine, LimitLabel },
|
components: { LimitLine, LimitLabel },
|
||||||
inject: ['openmct', 'domainObject', 'path'],
|
inject: ['openmct', 'domainObject', 'path', 'renderWhenVisible'],
|
||||||
props: {
|
props: {
|
||||||
rectangles: {
|
rectangles: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@ -199,7 +198,6 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
eventHelpers.extend(this);
|
eventHelpers.extend(this);
|
||||||
this.nicelyCalled = new NicelyCalled(this.$refs.chart);
|
|
||||||
this.seriesModels = [];
|
this.seriesModels = [];
|
||||||
this.config = this.getConfig();
|
this.config = this.getConfig();
|
||||||
this.isDestroyed = false;
|
this.isDestroyed = false;
|
||||||
@ -258,7 +256,6 @@ export default {
|
|||||||
},
|
},
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
this.nicelyCalled.destroy();
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getConfig() {
|
getConfig() {
|
||||||
@ -650,7 +647,7 @@ export default {
|
|||||||
},
|
},
|
||||||
scheduleDraw() {
|
scheduleDraw() {
|
||||||
if (!this.drawScheduled) {
|
if (!this.drawScheduled) {
|
||||||
const called = this.nicelyCalled.execute(this.draw);
|
const called = this.renderWhenVisible(this.draw);
|
||||||
this.drawScheduled = called;
|
this.drawScheduled = called;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -47,7 +47,7 @@ export default function OverlayPlotViewProvider(openmct) {
|
|||||||
let component = null;
|
let component = null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
show: function (element) {
|
show: function (element, isEditing, { renderWhenVisible }) {
|
||||||
let isCompact = isCompactView(objectPath);
|
let isCompact = isCompactView(objectPath);
|
||||||
const { vNode, destroy } = mount(
|
const { vNode, destroy } = mount(
|
||||||
{
|
{
|
||||||
@ -58,7 +58,8 @@ export default function OverlayPlotViewProvider(openmct) {
|
|||||||
provide: {
|
provide: {
|
||||||
openmct,
|
openmct,
|
||||||
domainObject,
|
domainObject,
|
||||||
path: objectPath
|
path: objectPath,
|
||||||
|
renderWhenVisible
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -25,6 +25,7 @@ import mount from 'utils/mount';
|
|||||||
import {
|
import {
|
||||||
createMouseEvent,
|
createMouseEvent,
|
||||||
createOpenMct,
|
createOpenMct,
|
||||||
|
renderWhenVisible,
|
||||||
resetApplicationState,
|
resetApplicationState,
|
||||||
spyOnBuiltins
|
spyOnBuiltins
|
||||||
} from 'utils/testing';
|
} from 'utils/testing';
|
||||||
@ -314,7 +315,8 @@ describe('the plugin', function () {
|
|||||||
openmct,
|
openmct,
|
||||||
domainObject: overlayPlotObject,
|
domainObject: overlayPlotObject,
|
||||||
composition,
|
composition,
|
||||||
path: [overlayPlotObject]
|
path: [overlayPlotObject],
|
||||||
|
renderWhenVisible
|
||||||
},
|
},
|
||||||
template: '<plot ref="plotComponent"></plot>'
|
template: '<plot ref="plotComponent"></plot>'
|
||||||
},
|
},
|
||||||
@ -505,7 +507,8 @@ describe('the plugin', function () {
|
|||||||
openmct: openmct,
|
openmct: openmct,
|
||||||
domainObject: overlayPlotObject,
|
domainObject: overlayPlotObject,
|
||||||
composition,
|
composition,
|
||||||
path: [overlayPlotObject]
|
path: [overlayPlotObject],
|
||||||
|
renderWhenVisible
|
||||||
},
|
},
|
||||||
template: '<plot ref="plotComponent"></plot>'
|
template: '<plot ref="plotComponent"></plot>'
|
||||||
},
|
},
|
||||||
|
@ -25,6 +25,7 @@ import mount from 'utils/mount';
|
|||||||
import {
|
import {
|
||||||
createMouseEvent,
|
createMouseEvent,
|
||||||
createOpenMct,
|
createOpenMct,
|
||||||
|
renderWhenVisible,
|
||||||
resetApplicationState,
|
resetApplicationState,
|
||||||
spyOnBuiltins
|
spyOnBuiltins
|
||||||
} from 'utils/testing';
|
} from 'utils/testing';
|
||||||
@ -372,7 +373,7 @@ describe('the plugin', function () {
|
|||||||
applicableViews = openmct.objectViews.get(testTelemetryObject, mockObjectPath);
|
applicableViews = openmct.objectViews.get(testTelemetryObject, mockObjectPath);
|
||||||
plotViewProvider = applicableViews.find((viewProvider) => viewProvider.key === 'plot-single');
|
plotViewProvider = applicableViews.find((viewProvider) => viewProvider.key === 'plot-single');
|
||||||
plotView = plotViewProvider.view(testTelemetryObject, []);
|
plotView = plotViewProvider.view(testTelemetryObject, []);
|
||||||
plotView.show(child, true);
|
plotView.show(child, true, { renderWhenVisible });
|
||||||
|
|
||||||
return nextTick();
|
return nextTick();
|
||||||
});
|
});
|
||||||
@ -654,7 +655,7 @@ describe('the plugin', function () {
|
|||||||
plotViewProvider = applicableViews.find((viewProvider) => viewProvider.key === 'plot-single');
|
plotViewProvider = applicableViews.find((viewProvider) => viewProvider.key === 'plot-single');
|
||||||
plotView = plotViewProvider.view(testTelemetryObject, []);
|
plotView = plotViewProvider.view(testTelemetryObject, []);
|
||||||
|
|
||||||
plotView.show(child, true);
|
plotView.show(child, true, { renderWhenVisible });
|
||||||
|
|
||||||
resizePromise = new Promise((resolve) => {
|
resizePromise = new Promise((resolve) => {
|
||||||
resizePromiseResolve = resolve;
|
resizePromiseResolve = resolve;
|
||||||
@ -811,7 +812,8 @@ describe('the plugin', function () {
|
|||||||
provide: {
|
provide: {
|
||||||
openmct: openmct,
|
openmct: openmct,
|
||||||
domainObject: selection[0][0].context.item,
|
domainObject: selection[0][0].context.item,
|
||||||
path: [selection[0][0].context.item, selection[0][1].context.item]
|
path: [selection[0][0].context.item, selection[0][1].context.item],
|
||||||
|
renderWhenVisible
|
||||||
},
|
},
|
||||||
template: '<plot-options ref="root"/>'
|
template: '<plot-options ref="root"/>'
|
||||||
},
|
},
|
||||||
|
@ -76,7 +76,7 @@ export default {
|
|||||||
StackedPlotItem,
|
StackedPlotItem,
|
||||||
PlotLegend
|
PlotLegend
|
||||||
},
|
},
|
||||||
inject: ['openmct', 'domainObject', 'path'],
|
inject: ['openmct', 'domainObject', 'path', 'renderWhenVisible'],
|
||||||
props: {
|
props: {
|
||||||
options: {
|
options: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -34,7 +34,7 @@ import conditionalStylesMixin from './mixins/objectStyles-mixin';
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [conditionalStylesMixin, stalenessMixin],
|
mixins: [conditionalStylesMixin, stalenessMixin],
|
||||||
inject: ['openmct', 'domainObject', 'path'],
|
inject: ['openmct', 'domainObject', 'path', 'renderWhenVisible'],
|
||||||
props: {
|
props: {
|
||||||
childObject: {
|
childObject: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -217,7 +217,8 @@ export default {
|
|||||||
provide: {
|
provide: {
|
||||||
openmct,
|
openmct,
|
||||||
domainObject: object,
|
domainObject: object,
|
||||||
path
|
path,
|
||||||
|
renderWhenVisible: this.renderWhenVisible
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -48,7 +48,7 @@ export default function StackedPlotViewProvider(openmct) {
|
|||||||
let component = null;
|
let component = null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
show: function (element) {
|
show: function (element, isEditing, { renderWhenVisible }) {
|
||||||
let isCompact = isCompactView(objectPath);
|
let isCompact = isCompactView(objectPath);
|
||||||
|
|
||||||
const { vNode, destroy } = mount(
|
const { vNode, destroy } = mount(
|
||||||
@ -60,7 +60,8 @@ export default function StackedPlotViewProvider(openmct) {
|
|||||||
provide: {
|
provide: {
|
||||||
openmct,
|
openmct,
|
||||||
domainObject,
|
domainObject,
|
||||||
path: objectPath
|
path: objectPath,
|
||||||
|
renderWhenVisible
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -25,6 +25,7 @@ import mount from 'utils/mount';
|
|||||||
import {
|
import {
|
||||||
createMouseEvent,
|
createMouseEvent,
|
||||||
createOpenMct,
|
createOpenMct,
|
||||||
|
renderWhenVisible,
|
||||||
resetApplicationState,
|
resetApplicationState,
|
||||||
spyOnBuiltins
|
spyOnBuiltins
|
||||||
} from 'utils/testing';
|
} from 'utils/testing';
|
||||||
@ -329,7 +330,8 @@ describe('the plugin', function () {
|
|||||||
provide: {
|
provide: {
|
||||||
openmct,
|
openmct,
|
||||||
domainObject: stackedPlotObject,
|
domainObject: stackedPlotObject,
|
||||||
path: [stackedPlotObject]
|
path: [stackedPlotObject],
|
||||||
|
renderWhenVisible
|
||||||
},
|
},
|
||||||
template: '<stacked-plot ref="stackedPlotRef"></stacked-plot>'
|
template: '<stacked-plot ref="stackedPlotRef"></stacked-plot>'
|
||||||
},
|
},
|
||||||
@ -619,7 +621,8 @@ describe('the plugin', function () {
|
|||||||
provide: {
|
provide: {
|
||||||
openmct: openmct,
|
openmct: openmct,
|
||||||
domainObject: selection[0][0].context.item,
|
domainObject: selection[0][0].context.item,
|
||||||
path: [selection[0][0].context.item]
|
path: [selection[0][0].context.item],
|
||||||
|
renderWhenVisible
|
||||||
},
|
},
|
||||||
template: '<plot-options/>'
|
template: '<plot-options/>'
|
||||||
},
|
},
|
||||||
@ -774,7 +777,8 @@ describe('the plugin', function () {
|
|||||||
provide: {
|
provide: {
|
||||||
openmct: openmct,
|
openmct: openmct,
|
||||||
domainObject: selection[0][0].context.item,
|
domainObject: selection[0][0].context.item,
|
||||||
path: [selection[0][0].context.item, selection[0][1].context.item]
|
path: [selection[0][0].context.item, selection[0][1].context.item],
|
||||||
|
renderWhenVisible
|
||||||
},
|
},
|
||||||
template: '<plot-options />'
|
template: '<plot-options />'
|
||||||
},
|
},
|
||||||
|
@ -65,7 +65,7 @@ export default class TelemetryTableView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
show(element, editMode) {
|
show(element, editMode, { renderWhenVisible }) {
|
||||||
const { vNode, destroy } = mount(
|
const { vNode, destroy } = mount(
|
||||||
{
|
{
|
||||||
el: element,
|
el: element,
|
||||||
@ -76,7 +76,8 @@ export default class TelemetryTableView {
|
|||||||
openmct: this.openmct,
|
openmct: this.openmct,
|
||||||
objectPath: this.objectPath,
|
objectPath: this.objectPath,
|
||||||
table: this.table,
|
table: this.table,
|
||||||
currentView: this
|
currentView: this,
|
||||||
|
renderWhenVisible
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -280,7 +280,6 @@ import { toRaw } from 'vue';
|
|||||||
|
|
||||||
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
||||||
|
|
||||||
import NicelyCalled from '../../../api/nice/NicelyCalled';
|
|
||||||
import CSVExporter from '../../../exporters/CSVExporter.js';
|
import CSVExporter from '../../../exporters/CSVExporter.js';
|
||||||
import ProgressBar from '../../../ui/components/ProgressBar.vue';
|
import ProgressBar from '../../../ui/components/ProgressBar.vue';
|
||||||
import Search from '../../../ui/components/SearchComponent.vue';
|
import Search from '../../../ui/components/SearchComponent.vue';
|
||||||
@ -306,7 +305,7 @@ export default {
|
|||||||
ProgressBar
|
ProgressBar
|
||||||
},
|
},
|
||||||
mixins: [stalenessMixin],
|
mixins: [stalenessMixin],
|
||||||
inject: ['openmct', 'objectPath', 'table', 'currentView'],
|
inject: ['openmct', 'objectPath', 'table', 'currentView', 'renderWhenVisible'],
|
||||||
props: {
|
props: {
|
||||||
isEditing: {
|
isEditing: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -481,7 +480,6 @@ export default {
|
|||||||
this.filterChanged = _.debounce(this.filterChanged, 500);
|
this.filterChanged = _.debounce(this.filterChanged, 500);
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.nicelyCalled = new NicelyCalled(this.$refs.root);
|
|
||||||
this.csvExporter = new CSVExporter();
|
this.csvExporter = new CSVExporter();
|
||||||
this.rowsAdded = _.throttle(this.rowsAdded, 200);
|
this.rowsAdded = _.throttle(this.rowsAdded, 200);
|
||||||
this.rowsRemoved = _.throttle(this.rowsRemoved, 200);
|
this.rowsRemoved = _.throttle(this.rowsRemoved, 200);
|
||||||
@ -547,13 +545,11 @@ export default {
|
|||||||
this.table.configuration.destroy();
|
this.table.configuration.destroy();
|
||||||
|
|
||||||
this.table.destroy();
|
this.table.destroy();
|
||||||
|
|
||||||
this.nicelyCalled.destroy();
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateVisibleRows() {
|
updateVisibleRows() {
|
||||||
if (!this.updatingView) {
|
if (!this.updatingView) {
|
||||||
this.updatingView = this.nicelyCalled.execute(() => {
|
this.updatingView = this.renderWhenVisible(() => {
|
||||||
let start = 0;
|
let start = 0;
|
||||||
let end = VISIBLE_ROW_COUNT;
|
let end = VISIBLE_ROW_COUNT;
|
||||||
let tableRows = this.table.tableRows.getRows();
|
let tableRows = this.table.tableRows.getRows();
|
||||||
@ -829,7 +825,7 @@ export default {
|
|||||||
let scrollTop = this.scrollable.scrollTop;
|
let scrollTop = this.scrollable.scrollTop;
|
||||||
|
|
||||||
this.resizePollHandle = setInterval(() => {
|
this.resizePollHandle = setInterval(() => {
|
||||||
this.nicelyCalled.execute(() => {
|
this.renderWhenVisible(() => {
|
||||||
if ((el.clientWidth !== width || el.clientHeight !== height) && this.isAutosizeEnabled) {
|
if ((el.clientWidth !== width || el.clientHeight !== height) && this.isAutosizeEnabled) {
|
||||||
this.calculateTableSize();
|
this.calculateTableSize();
|
||||||
// On some resize events scrollTop is reset to 0. Possibly due to a transition we're using?
|
// On some resize events scrollTop is reset to 0. Possibly due to a transition we're using?
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
import {
|
import {
|
||||||
createMouseEvent,
|
createMouseEvent,
|
||||||
createOpenMct,
|
createOpenMct,
|
||||||
|
renderWhenVisible,
|
||||||
resetApplicationState,
|
resetApplicationState,
|
||||||
spyOnBuiltins
|
spyOnBuiltins
|
||||||
} from 'utils/testing';
|
} from 'utils/testing';
|
||||||
@ -236,7 +237,7 @@ describe('the plugin', () => {
|
|||||||
applicableViews = openmct.objectViews.get(testTelemetryObject, []);
|
applicableViews = openmct.objectViews.get(testTelemetryObject, []);
|
||||||
tableViewProvider = applicableViews.find((viewProvider) => viewProvider.key === 'table');
|
tableViewProvider = applicableViews.find((viewProvider) => viewProvider.key === 'table');
|
||||||
tableView = tableViewProvider.view(testTelemetryObject, [testTelemetryObject]);
|
tableView = tableViewProvider.view(testTelemetryObject, [testTelemetryObject]);
|
||||||
tableView.show(child, true);
|
tableView.show(child, true, { renderWhenVisible });
|
||||||
|
|
||||||
tableInstance = tableView.getTable();
|
tableInstance = tableView.getTable();
|
||||||
|
|
||||||
|
@ -33,6 +33,8 @@ import StyleRuleManager from '@/plugins/condition/StyleRuleManager';
|
|||||||
import { STYLE_CONSTANTS } from '@/plugins/condition/utils/constants';
|
import { STYLE_CONSTANTS } from '@/plugins/condition/utils/constants';
|
||||||
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
import stalenessMixin from '@/ui/mixins/staleness-mixin';
|
||||||
|
|
||||||
|
import VisibilityObserver from '../../utils/visibility/VisibilityObserver';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [stalenessMixin],
|
mixins: [stalenessMixin],
|
||||||
inject: ['openmct'],
|
inject: ['openmct'],
|
||||||
@ -113,6 +115,9 @@ export default {
|
|||||||
this.actionCollection.destroy();
|
this.actionCollection.destroy();
|
||||||
delete this.actionCollection;
|
delete this.actionCollection;
|
||||||
}
|
}
|
||||||
|
if (this.visibilityObserver) {
|
||||||
|
this.visibilityObserver.destroy();
|
||||||
|
}
|
||||||
this.$refs.objectViewWrapper.removeEventListener('dragover', this.onDragOver, {
|
this.$refs.objectViewWrapper.removeEventListener('dragover', this.onDragOver, {
|
||||||
capture: true
|
capture: true
|
||||||
});
|
});
|
||||||
@ -125,6 +130,7 @@ export default {
|
|||||||
this.debounceUpdateView = _.debounce(this.updateView, 10);
|
this.debounceUpdateView = _.debounce(this.updateView, 10);
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.visibilityObserver = new VisibilityObserver(this.$refs.objectViewWrapper);
|
||||||
this.updateView();
|
this.updateView();
|
||||||
this.$refs.objectViewWrapper.addEventListener('dragover', this.onDragOver, {
|
this.$refs.objectViewWrapper.addEventListener('dragover', this.onDragOver, {
|
||||||
capture: true
|
capture: true
|
||||||
@ -290,7 +296,9 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentView.show(this.viewContainer, this.openmct.editor.isEditing());
|
this.currentView.show(this.viewContainer, this.openmct.editor.isEditing(), {
|
||||||
|
renderWhenVisible: this.visibilityObserver.renderWhenVisible
|
||||||
|
});
|
||||||
|
|
||||||
if (immediatelySelect) {
|
if (immediatelySelect) {
|
||||||
this.removeSelectable = this.openmct.selection.selectable(
|
this.removeSelectable = this.openmct.selection.selectable(
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="l-preview-window js-preview-window">
|
<div class="l-preview-window js-preview-window">
|
||||||
<PreviewHeader
|
<PreviewHeader
|
||||||
|
ref="previewHeader"
|
||||||
:current-view="currentViewProvider"
|
:current-view="currentViewProvider"
|
||||||
:action-collection="actionCollection"
|
:action-collection="actionCollection"
|
||||||
:domain-object="domainObject"
|
:domain-object="domainObject"
|
||||||
@ -48,7 +49,7 @@ export default {
|
|||||||
viewOptions: {
|
viewOptions: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default() {
|
default() {
|
||||||
return undefined;
|
return {};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
existingView: {
|
existingView: {
|
||||||
@ -147,6 +148,11 @@ export default {
|
|||||||
if (isExistingView) {
|
if (isExistingView) {
|
||||||
this.viewContainer.appendChild(this.existingViewElement);
|
this.viewContainer.appendChild(this.existingViewElement);
|
||||||
} else {
|
} else {
|
||||||
|
// in preview mode, we're always visible
|
||||||
|
this.viewOptions.renderWhenVisible = (func) => {
|
||||||
|
window.requestAnimationFrame(func);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
this.view.show(this.viewContainer, false, this.viewOptions);
|
this.view.show(this.viewContainer, false, this.viewOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,6 +279,12 @@ export function getMockTelemetry(opts = {}) {
|
|||||||
return telemetry;
|
return telemetry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// used to inject into tests that require a render
|
||||||
|
export function renderWhenVisible(func) {
|
||||||
|
func();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// copy objects a bit more easily
|
// copy objects a bit more easily
|
||||||
function copyObj(obj) {
|
function copyObj(obj) {
|
||||||
return JSON.parse(JSON.stringify(obj));
|
return JSON.parse(JSON.stringify(obj));
|
||||||
|
@ -23,36 +23,38 @@
|
|||||||
/**
|
/**
|
||||||
* Optimizes `requestAnimationFrame` calls to only execute when the element is visible in the viewport.
|
* Optimizes `requestAnimationFrame` calls to only execute when the element is visible in the viewport.
|
||||||
*/
|
*/
|
||||||
export default class NicelyCalled {
|
export default class VisibilityObserver {
|
||||||
#element;
|
#element;
|
||||||
#isIntersecting;
|
|
||||||
#observer;
|
#observer;
|
||||||
#lastUnfiredFunc;
|
lastUnfiredFunc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a NicelyCalled instance to manage visibility-based requestAnimationFrame calls.
|
* Constructs a VisibilityObserver instance to manage visibility-based requestAnimationFrame calls.
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} element - The DOM element to observe for visibility changes.
|
* @param {HTMLElement} element - The DOM element to observe for visibility changes.
|
||||||
* @throws {Error} If element is not provided.
|
* @throws {Error} If element is not provided.
|
||||||
*/
|
*/
|
||||||
constructor(element) {
|
constructor(element) {
|
||||||
if (!element) {
|
if (!element) {
|
||||||
throw new Error(`Nice visibility must be created with an element`);
|
throw new Error(`VisibilityObserver must be created with an element`);
|
||||||
}
|
}
|
||||||
|
// set the id to some random 4 letters
|
||||||
|
this.id = Math.random().toString(36).substring(2, 6);
|
||||||
this.#element = element;
|
this.#element = element;
|
||||||
this.#isIntersecting = true;
|
this.isIntersecting = true;
|
||||||
|
|
||||||
this.#observer = new IntersectionObserver(this.#observerCallback);
|
this.#observer = new IntersectionObserver(this.#observerCallback);
|
||||||
this.#observer.observe(this.#element);
|
this.#observer.observe(this.#element);
|
||||||
this.#lastUnfiredFunc = null;
|
this.lastUnfiredFunc = null;
|
||||||
|
this.renderWhenVisible = this.renderWhenVisible.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
#observerCallback = ([entry]) => {
|
#observerCallback = ([entry]) => {
|
||||||
if (entry.target === this.#element) {
|
if (entry.target === this.#element) {
|
||||||
this.#isIntersecting = entry.isIntersecting;
|
this.isIntersecting = entry.isIntersecting;
|
||||||
if (this.#isIntersecting && this.#lastUnfiredFunc) {
|
if (this.isIntersecting && this.lastUnfiredFunc) {
|
||||||
window.requestAnimationFrame(this.#lastUnfiredFunc);
|
window.requestAnimationFrame(this.lastUnfiredFunc);
|
||||||
this.#lastUnfiredFunc = null;
|
this.lastUnfiredFunc = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -65,12 +67,12 @@ export default class NicelyCalled {
|
|||||||
* @param {Function} func - The function to execute.
|
* @param {Function} func - The function to execute.
|
||||||
* @returns {boolean} True if the function was executed immediately, false otherwise.
|
* @returns {boolean} True if the function was executed immediately, false otherwise.
|
||||||
*/
|
*/
|
||||||
execute(func) {
|
renderWhenVisible(func) {
|
||||||
if (this.#isIntersecting) {
|
if (this.isIntersecting) {
|
||||||
window.requestAnimationFrame(func);
|
window.requestAnimationFrame(func);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
this.#lastUnfiredFunc = func;
|
this.lastUnfiredFunc = func;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,8 +83,8 @@ export default class NicelyCalled {
|
|||||||
destroy() {
|
destroy() {
|
||||||
this.#observer.unobserve(this.#element);
|
this.#observer.unobserve(this.#element);
|
||||||
this.#element = null;
|
this.#element = null;
|
||||||
this.#isIntersecting = null;
|
this.isIntersecting = null;
|
||||||
this.#observer = null;
|
this.#observer = null;
|
||||||
this.#lastUnfiredFunc = null;
|
this.lastUnfiredFunc = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user