Merged in bugfix/topic-background (pull request #14)

Fix topic background

* Fix Textpeer getNativePosition implementation (broken with jQuery removal)

* Remove time-bound waits from cypress tests


Approved-by: Paulo Veiga
This commit is contained in:
Matias Arriola 2021-12-21 18:05:03 +00:00 committed by Paulo Veiga
parent 60771b2ded
commit 5c2a96682d
8 changed files with 85 additions and 12 deletions

View File

@ -10,18 +10,19 @@ context('Playground', () => {
}); });
it('the playground viewmode.html page should match its snapshot', () => { it('the playground viewmode.html page should match its snapshot', () => {
cy.visit('/viewmode.html'); cy.visit('/viewmode.html');
cy.get('#mindplot.ready').should('exist');
cy.matchImageSnapshot('viewmode'); cy.matchImageSnapshot('viewmode');
}); });
it('the playground container.html page should match its snapshot', () => { it('the playground container.html page should match its snapshot', () => {
cy.visit('/container.html'); cy.visit('/container.html');
// TODO: wait for mind map to load instead of an arbitrary number of ms cy.getIframeBody()
cy.wait(5000); .find('#mindplot.ready')
.should('exist');
cy.matchImageSnapshot('container'); cy.matchImageSnapshot('container');
}); });
it('the playground editor.html page should match its snapshot', () => { it('the playground editor.html page should match its snapshot', () => {
cy.visit('/editor.html'); cy.visit('/editor.html');
// TODO: wait for mind map to load instead of an arbitrary number of ms cy.get('#mindplot.ready').should('exist');
cy.wait(5000);
// TODO: why is the editor appearing twice in the snapshot? // TODO: why is the editor appearing twice in the snapshot?
cy.matchImageSnapshot('editor'); cy.matchImageSnapshot('editor');
}); });

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 73 KiB

View File

@ -13,3 +13,9 @@ if (Cypress.env('imageSnaphots')) {
() => Promise.resolve(), () => Promise.resolve(),
); );
} }
// https://www.cypress.io/blog/2020/02/12/working-with-iframes-in-cypress/
Cypress.Commands.add('getIframeBody', () => cy
.get('iframe')
.its('0.contentDocument.body').should('not.be.empty')
.then(cy.wrap));

View File

@ -7,6 +7,10 @@ const example = async () => {
const options = await loadDesignerOptions(); const options = await loadDesignerOptions();
const designer = buildDesigner(options); const designer = buildDesigner(options);
designer.addEvent('loadSuccess', () => {
document.getElementById('mindplot').classList.add('ready');
});
// Load map from XML file persisted on disk... // Load map from XML file persisted on disk...
const persistence = PersistenceManager.getInstance(); const persistence = PersistenceManager.getInstance();
const mindmap = persistence.load(mapId); const mindmap = persistence.load(mapId);

View File

@ -10,6 +10,9 @@ const example = async () => {
const options = await loadDesignerOptions(confUrl); const options = await loadDesignerOptions(confUrl);
const designer = buildDesigner(options); const designer = buildDesigner(options);
designer.addEvent('loadSuccess', () => {
document.getElementById('mindplot').classList.add('ready');
});
// Load map from XML file persisted on disk... // Load map from XML file persisted on disk...
const persistence = PersistenceManager.getInstance(); const persistence = PersistenceManager.getInstance();
let mindmap; let mindmap;

View File

@ -8,7 +8,9 @@ const example = async () => {
const options = await loadDesignerOptions(); const options = await loadDesignerOptions();
options.readOnly = true; options.readOnly = true;
const designer = buildDesigner(options); const designer = buildDesigner(options);
designer.addEvent('loadSuccess', () => {
document.getElementById('mindplot').classList.add('ready');
});
// Load map from XML file persisted on disk... // Load map from XML file persisted on disk...
const persistence = PersistenceManager.getInstance(); const persistence = PersistenceManager.getInstance();
let mindmap; let mindmap;

View File

@ -17,6 +17,7 @@
*/ */
import { $defined } from '@wisemapping/core-js'; import { $defined } from '@wisemapping/core-js';
import ElementPeer from './ElementPeer'; import ElementPeer from './ElementPeer';
import { getPosition } from '../utils/DomUtils';
class TextPeer extends ElementPeer { class TextPeer extends ElementPeer {
constructor(Font) { constructor(Font) {
@ -80,13 +81,7 @@ class TextPeer extends ElementPeer {
} }
getNativePosition() { getNativePosition() {
const computedStyles = window.getComputedStyle(this._native); return getPosition(this._native);
const marginTop = computedStyles.getPropertyValue('margin-top') || 0;
const marginLeft = computedStyles.getPropertyValue('margin-left') || 0;
return {
top: this._native.offsetTop - parseFloat(marginTop),
left: this._native.offsetLeft - parseFloat(marginLeft),
};
} }
setFont(font, size, style, weight) { setFont(font, size, style, weight) {

View File

@ -0,0 +1,62 @@
/* eslint-disable import/prefer-default-export */
// quick hand-made version of $.css()
export const getStyle = (elem, prop) => {
const result = window.getComputedStyle(elem)[prop];
if (typeof result === 'string' && /px$/.test(result)) {
return parseFloat(result);
}
return result;
};
// offset and position utils extracted and adapted from jquery source
// https://github.com/jquery/jquery/blob/main/src/offset.js
export const getOffset = (elem) => {
if (!elem || !elem.getClientRects().length) {
return { top: 0, left: 0 };
}
// Get document-relative position by adding viewport scroll to viewport-relative gBCR
const rect = elem.getBoundingClientRect();
const win = elem.ownerDocument.defaultView;
return {
top: rect.top + win.pageYOffset,
left: rect.left + win.pageXOffset,
};
};
export const getPosition = (elem) => {
let offsetParent;
let offset;
let doc;
let parentOffset = { top: 0, left: 0 };
// position:fixed elements are offset from the viewport, which itself always has zero offset
if (getStyle(elem, 'position') === 'fixed') {
// Assume position:fixed implies availability of getBoundingClientRect
offset = elem.getBoundingClientRect();
} else {
offset = getOffset(elem);
// Account for the *real* offset parent, which can be the document or its root element
// when a statically positioned element is identified
doc = elem.ownerDocument;
offsetParent = elem.offsetParent || doc.documentElement;
while (offsetParent
&& (offsetParent === doc.body || offsetParent === doc.documentElement)
&& getStyle(offsetParent, 'position') === 'static') {
offsetParent = offsetParent.parentNode;
}
if (offsetParent && offsetParent !== elem && offsetParent.nodeType === 1) {
// Incorporate borders into its offset, since they are outside its content origin
parentOffset = getOffset(offsetParent);
parentOffset.top += getStyle(offsetParent, 'borderTopWidth');
parentOffset.left += getStyle(offsetParent, 'borderLeftWidth');
}
}
// Subtract parent offsets and element margins
return {
top: offset.top - parentOffset.top - getStyle(elem, 'marginTop'),
left: offset.left - parentOffset.left - getStyle(elem, 'marginLeft'),
};
};