MOBILE-3814 dom: Improve element position
parent
a76914f25a
commit
d500d1fd08
|
@ -78,13 +78,18 @@ export class AddonQtypeDdImageOrTextQuestion {
|
||||||
return bgImgXY;
|
return bgImgXY;
|
||||||
}
|
}
|
||||||
|
|
||||||
const position = CoreDomUtils.getElementXY(bgImg, undefined, 'ddarea');
|
const ddArea = this.container.querySelector<HTMLElement>('.ddarea');
|
||||||
|
if (!ddArea) {
|
||||||
|
return bgImgXY;
|
||||||
|
}
|
||||||
|
|
||||||
|
const position = CoreDomUtils.getRelativeElementPosition(bgImg, ddArea);
|
||||||
|
|
||||||
// Render the position related to the current image dimensions.
|
// Render the position related to the current image dimensions.
|
||||||
bgImgXY[0] *= this.proportion;
|
bgImgXY[0] *= this.proportion;
|
||||||
bgImgXY[1] *= this.proportion;
|
bgImgXY[1] *= this.proportion;
|
||||||
|
|
||||||
return [Number(bgImgXY[0]) + position[0] + 1, Number(bgImgXY[1]) + position[1] + 1];
|
return [bgImgXY[0] + position.x + 1, bgImgXY[1] + position.y + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -409,10 +414,15 @@ export class AddonQtypeDdImageOrTextQuestion {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now position the draggable and set it to the input.
|
// Now position the draggable and set it to the input.
|
||||||
const position = CoreDomUtils.getElementXY(drop, undefined, 'ddarea');
|
const ddArea = this.container.querySelector<HTMLElement>('.ddarea');
|
||||||
|
if (!ddArea) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const position = CoreDomUtils.getRelativeElementPosition(drop, ddArea);
|
||||||
const choice = drag.getAttribute('choice');
|
const choice = drag.getAttribute('choice');
|
||||||
drag.style.left = position[0] - 1 + 'px';
|
drag.style.left = position.x + 'px';
|
||||||
drag.style.top = position[1] - 1 + 'px';
|
drag.style.top = position.y + 'px';
|
||||||
drag.classList.add('placed');
|
drag.classList.add('placed');
|
||||||
|
|
||||||
if (choice) {
|
if (choice) {
|
||||||
|
@ -458,13 +468,14 @@ export class AddonQtypeDdImageOrTextQuestion {
|
||||||
|
|
||||||
// Move the element to its original position.
|
// Move the element to its original position.
|
||||||
const dragItemHome = this.doc.dragItemHome(Number(drag.getAttribute('dragitemno')));
|
const dragItemHome = this.doc.dragItemHome(Number(drag.getAttribute('dragitemno')));
|
||||||
if (!dragItemHome) {
|
const ddArea = this.container.querySelector<HTMLElement>('.ddarea');
|
||||||
|
if (!dragItemHome || !ddArea) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const position = CoreDomUtils.getElementXY(dragItemHome, undefined, 'ddarea');
|
const position = CoreDomUtils.getRelativeElementPosition(dragItemHome, ddArea);
|
||||||
drag.style.left = position[0] + 'px';
|
drag.style.left = position.x + 'px';
|
||||||
drag.style.top = position[1] + 'px';
|
drag.style.top = position.y + 'px';
|
||||||
drag.classList.remove('placed');
|
drag.classList.remove('placed');
|
||||||
|
|
||||||
drag.setAttribute('inputid', '');
|
drag.setAttribute('inputid', '');
|
||||||
|
|
|
@ -12,21 +12,13 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreCoordinates, CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreEventObserver } from '@singletons/events';
|
import { CoreEventObserver } from '@singletons/events';
|
||||||
import { CoreLogger } from '@singletons/logger';
|
import { CoreLogger } from '@singletons/logger';
|
||||||
import { AddonQtypeDdMarkerQuestionData } from '../component/ddmarker';
|
import { AddonQtypeDdMarkerQuestionData } from '../component/ddmarker';
|
||||||
import { AddonQtypeDdMarkerGraphicsApi } from './graphics_api';
|
import { AddonQtypeDdMarkerGraphicsApi } from './graphics_api';
|
||||||
|
|
||||||
/**
|
|
||||||
* Point type.
|
|
||||||
*/
|
|
||||||
export type AddonQtypeDdMarkerQuestionPoint = {
|
|
||||||
x: number; // X axis coordinates.
|
|
||||||
y: number; // Y axis coordinates.
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to make a question of ddmarker type work.
|
* Class to make a question of ddmarker type work.
|
||||||
*/
|
*/
|
||||||
|
@ -36,8 +28,7 @@ export class AddonQtypeDdMarkerQuestion {
|
||||||
|
|
||||||
protected logger: CoreLogger;
|
protected logger: CoreLogger;
|
||||||
protected afterImageLoadDone = false;
|
protected afterImageLoadDone = false;
|
||||||
protected drops;
|
protected topNode?: HTMLElement | null;
|
||||||
protected topNode;
|
|
||||||
protected nextColourIndex = 0;
|
protected nextColourIndex = 0;
|
||||||
protected proportion = 1;
|
protected proportion = 1;
|
||||||
protected selected?: HTMLElement; // Selected element (being "dragged").
|
protected selected?: HTMLElement; // Selected element (being "dragged").
|
||||||
|
@ -123,7 +114,7 @@ export class AddonQtypeDdMarkerQuestion {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const position = CoreDomUtils.getElementXY(bgImg, undefined, 'ddarea');
|
const position = this.getElementCoordinates(bgImg);
|
||||||
let coordsNumbers = this.parsePoint(bgImgXY);
|
let coordsNumbers = this.parsePoint(bgImgXY);
|
||||||
|
|
||||||
coordsNumbers = this.makePointProportional(coordsNumbers);
|
coordsNumbers = this.makePointProportional(coordsNumbers);
|
||||||
|
@ -131,13 +122,30 @@ export class AddonQtypeDdMarkerQuestion {
|
||||||
return [coordsNumbers.x + position[0], coordsNumbers.y + position[1]];
|
return [coordsNumbers.x + position[0], coordsNumbers.y + position[1]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns elements coordinates relative to ddarea container.
|
||||||
|
*
|
||||||
|
* @param element Element.
|
||||||
|
* @return Array of X and Y coordinates.
|
||||||
|
*/
|
||||||
|
protected getElementCoordinates(element: HTMLElement): number[] {
|
||||||
|
const ddArea = this.container.querySelector<HTMLElement>('.ddarea');
|
||||||
|
if (!ddArea) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const position = CoreDomUtils.getRelativeElementPosition(element, ddArea);
|
||||||
|
|
||||||
|
return [position.x, position.y];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if some coordinates (X, Y) are inside the background image.
|
* Check if some coordinates (X, Y) are inside the background image.
|
||||||
*
|
*
|
||||||
* @param coords Coordinates to check.
|
* @param coords Coordinates to check.
|
||||||
* @return Whether they're inside the background image.
|
* @return Whether they're inside the background image.
|
||||||
*/
|
*/
|
||||||
coordsInImg(coords: AddonQtypeDdMarkerQuestionPoint): boolean {
|
coordsInImg(coords: CoreCoordinates): boolean {
|
||||||
const bgImg = this.doc.bgImg();
|
const bgImg = this.doc.bgImg();
|
||||||
if (!bgImg) {
|
if (!bgImg) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -177,13 +185,13 @@ export class AddonQtypeDdMarkerQuestion {
|
||||||
const dragging = this.selected;
|
const dragging = this.selected;
|
||||||
if (dragging && !drag.classList.contains('unplaced')) {
|
if (dragging && !drag.classList.contains('unplaced')) {
|
||||||
|
|
||||||
const position = CoreDomUtils.getElementXY(drag, undefined, 'ddarea');
|
const position = this.getElementCoordinates(drag);
|
||||||
const bgImg = this.doc.bgImg();
|
const bgImg = this.doc.bgImg();
|
||||||
if (!bgImg) {
|
if (!bgImg) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bgImgPos = CoreDomUtils.getElementXY(bgImg, undefined, 'ddarea');
|
const bgImgPos = this.getElementCoordinates(bgImg);
|
||||||
|
|
||||||
position[0] = position[0] - bgImgPos[0] + e.offsetX;
|
position[0] = position[0] - bgImgPos[0] + e.offsetX;
|
||||||
position[1] = position[1] - bgImgPos[1] + e.offsetY;
|
position[1] = position[1] - bgImgPos[1] + e.offsetY;
|
||||||
|
@ -217,7 +225,7 @@ export class AddonQtypeDdMarkerQuestion {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const position = CoreDomUtils.getElementXY(dragItemHome, undefined, 'ddarea');
|
const position = this.getElementCoordinates(dragItemHome);
|
||||||
|
|
||||||
return [position[0], position[1]];
|
return [position[0], position[1]];
|
||||||
}
|
}
|
||||||
|
@ -317,7 +325,7 @@ export class AddonQtypeDdMarkerQuestion {
|
||||||
* @param colour Colour of the circle.
|
* @param colour Colour of the circle.
|
||||||
* @return X and Y position of the center of the circle.
|
* @return X and Y position of the center of the circle.
|
||||||
*/
|
*/
|
||||||
drawShapeCircle(dropZoneNo: number, coordinates: string, colour: string): AddonQtypeDdMarkerQuestionPoint | null {
|
drawShapeCircle(dropZoneNo: number, coordinates: string, colour: string): CoreCoordinates | null {
|
||||||
if (!coordinates.match(/^\d+(\.\d+)?,\d+(\.\d+)?;\d+(\.\d+)?$/)) {
|
if (!coordinates.match(/^\d+(\.\d+)?,\d+(\.\d+)?;\d+(\.\d+)?$/)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -356,7 +364,7 @@ export class AddonQtypeDdMarkerQuestion {
|
||||||
* @param colour Colour of the rectangle.
|
* @param colour Colour of the rectangle.
|
||||||
* @return X and Y position of the center of the rectangle.
|
* @return X and Y position of the center of the rectangle.
|
||||||
*/
|
*/
|
||||||
drawShapeRectangle(dropZoneNo: number, coordinates: string, colour: string): AddonQtypeDdMarkerQuestionPoint | null {
|
drawShapeRectangle(dropZoneNo: number, coordinates: string, colour: string): CoreCoordinates | null {
|
||||||
if (!coordinates.match(/^\d+(\.\d+)?,\d+(\.\d+)?;\d+(\.\d+)?,\d+(\.\d+)?$/)) {
|
if (!coordinates.match(/^\d+(\.\d+)?,\d+(\.\d+)?;\d+(\.\d+)?,\d+(\.\d+)?$/)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -399,7 +407,7 @@ export class AddonQtypeDdMarkerQuestion {
|
||||||
* @param colour Colour of the polygon.
|
* @param colour Colour of the polygon.
|
||||||
* @return X and Y position of the center of the polygon.
|
* @return X and Y position of the center of the polygon.
|
||||||
*/
|
*/
|
||||||
drawShapePolygon(dropZoneNo: number, coordinates: string, colour: string): AddonQtypeDdMarkerQuestionPoint | null {
|
drawShapePolygon(dropZoneNo: number, coordinates: string, colour: string): CoreCoordinates | null {
|
||||||
if (!coordinates.match(/^\d+(\.\d+)?,\d+(\.\d+)?(?:;\d+(\.\d+)?,\d+(\.\d+)?)*$/)) {
|
if (!coordinates.match(/^\d+(\.\d+)?,\d+(\.\d+)?(?:;\d+(\.\d+)?,\d+(\.\d+)?)*$/)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -449,7 +457,7 @@ export class AddonQtypeDdMarkerQuestion {
|
||||||
* @param coordinates "x,y".
|
* @param coordinates "x,y".
|
||||||
* @return Coordinates to the point.
|
* @return Coordinates to the point.
|
||||||
*/
|
*/
|
||||||
parsePoint(coordinates: string): AddonQtypeDdMarkerQuestionPoint {
|
parsePoint(coordinates: string): CoreCoordinates {
|
||||||
const bits = coordinates.split(',');
|
const bits = coordinates.split(',');
|
||||||
if (bits.length !== 2) {
|
if (bits.length !== 2) {
|
||||||
throw coordinates + ' is not a valid point';
|
throw coordinates + ' is not a valid point';
|
||||||
|
@ -464,7 +472,7 @@ export class AddonQtypeDdMarkerQuestion {
|
||||||
* @param point Point coordinates.
|
* @param point Point coordinates.
|
||||||
* @return Converted point.
|
* @return Converted point.
|
||||||
*/
|
*/
|
||||||
makePointProportional(point: AddonQtypeDdMarkerQuestionPoint): AddonQtypeDdMarkerQuestionPoint {
|
makePointProportional(point: CoreCoordinates): CoreCoordinates {
|
||||||
return {
|
return {
|
||||||
x: Math.round(point.x * this.proportion),
|
x: Math.round(point.x * this.proportion),
|
||||||
y: Math.round(point.y * this.proportion),
|
y: Math.round(point.y * this.proportion),
|
||||||
|
@ -542,10 +550,10 @@ export class AddonQtypeDdMarkerQuestion {
|
||||||
* @return Coordinates.
|
* @return Coordinates.
|
||||||
*/
|
*/
|
||||||
getDragXY(dragItem: HTMLElement): number[] {
|
getDragXY(dragItem: HTMLElement): number[] {
|
||||||
const position = CoreDomUtils.getElementXY(dragItem, undefined, 'ddarea');
|
const position = this.getElementCoordinates(dragItem);
|
||||||
const bgImg = this.doc.bgImg();
|
const bgImg = this.doc.bgImg();
|
||||||
if (bgImg) {
|
if (bgImg) {
|
||||||
const bgImgXY = CoreDomUtils.getElementXY(bgImg, undefined, 'ddarea');
|
const bgImgXY = this.getElementCoordinates(bgImg);
|
||||||
|
|
||||||
position[0] -= bgImgXY[0];
|
position[0] -= bgImgXY[0];
|
||||||
position[1] -= bgImgXY[1];
|
position[1] -= bgImgXY[1];
|
||||||
|
|
|
@ -23,12 +23,6 @@ export class AddonQtypeDdMarkerGraphicsApi {
|
||||||
protected readonly NS = 'http://www.w3.org/2000/svg';
|
protected readonly NS = 'http://www.w3.org/2000/svg';
|
||||||
protected dropZone?: SVGSVGElement;
|
protected dropZone?: SVGSVGElement;
|
||||||
|
|
||||||
/**
|
|
||||||
* Create the instance.
|
|
||||||
*
|
|
||||||
* @param instance Question instance.
|
|
||||||
* @param domUtils Dom Utils provider.
|
|
||||||
*/
|
|
||||||
constructor(protected instance: AddonQtypeDdMarkerQuestion) { }
|
constructor(protected instance: AddonQtypeDdMarkerQuestion) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,20 +54,20 @@ export class AddonQtypeDdMarkerGraphicsApi {
|
||||||
const bgImg = this.instance.doc?.bgImg();
|
const bgImg = this.instance.doc?.bgImg();
|
||||||
const dropZones = this.instance.doc?.topNode?.querySelector<HTMLElement>('div.ddarea div.dropzones');
|
const dropZones = this.instance.doc?.topNode?.querySelector<HTMLElement>('div.ddarea div.dropzones');
|
||||||
const markerTexts = this.instance.doc?.markerTexts();
|
const markerTexts = this.instance.doc?.markerTexts();
|
||||||
|
const ddArea = this.instance.doc?.topNode?.querySelector<HTMLElement>('.ddarea');
|
||||||
if (!bgImg || !dropZones || !markerTexts) {
|
if (!bgImg || !dropZones || !markerTexts || !ddArea) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const position = CoreDomUtils.getElementXY(bgImg, undefined, 'ddarea');
|
const position = CoreDomUtils.getRelativeElementPosition(bgImg, ddArea);
|
||||||
|
|
||||||
dropZones.style.left = position[0] + 'px';
|
dropZones.style.left = position.x + 'px';
|
||||||
dropZones.style.top = position[1] + 'px';
|
dropZones.style.top = position.y + 'px';
|
||||||
dropZones.style.width = bgImg.width + 'px';
|
dropZones.style.width = bgImg.width + 'px';
|
||||||
dropZones.style.height = bgImg.height + 'px';
|
dropZones.style.height = bgImg.height + 'px';
|
||||||
|
|
||||||
markerTexts.style.left = position[0] + 'px';
|
markerTexts.style.left = position.x + 'px';
|
||||||
markerTexts.style.top = position[1] + 'px';
|
markerTexts.style.top = position.y + 'px';
|
||||||
markerTexts.style.width = bgImg.width + 'px';
|
markerTexts.style.width = bgImg.width + 'px';
|
||||||
markerTexts.style.height = bgImg.height + 'px';
|
markerTexts.style.height = bgImg.height + 'px';
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreFormatTextDirective } from '@directives/format-text';
|
import { CoreFormatTextDirective } from '@directives/format-text';
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreCoordinates, CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { CoreComponentsRegistry } from '@singletons/components-registry';
|
import { CoreComponentsRegistry } from '@singletons/components-registry';
|
||||||
|
@ -375,33 +375,37 @@ export class AddonQtypeDdwtosQuestion {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let position;
|
|
||||||
|
|
||||||
const placeNo = this.placed[this.getNo(drag) ?? -1];
|
const placeNo = this.placed[this.getNo(drag) ?? -1];
|
||||||
|
const parent = this.container.querySelector<HTMLElement>('.addon-qtype-ddwtos-container');
|
||||||
|
if (!parent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let position: CoreCoordinates | undefined;
|
||||||
|
|
||||||
if (!placeNo) {
|
if (!placeNo) {
|
||||||
// Not placed, put it in home zone.
|
// Not placed, put it in home zone.
|
||||||
const groupNo = this.getGroup(drag) ?? -1;
|
const groupNo = this.getGroup(drag) ?? -1;
|
||||||
const choiceNo = this.getChoice(drag) ?? -1;
|
const choiceNo = this.getChoice(drag) ?? -1;
|
||||||
|
const dragHome = this.container.querySelector<HTMLElement>(this.selectors.dragHome(groupNo, choiceNo));
|
||||||
position = CoreDomUtils.getElementXY(
|
if (dragHome) {
|
||||||
this.container,
|
position = CoreDomUtils.getRelativeElementPosition(dragHome, parent);
|
||||||
this.selectors.dragHome(groupNo, choiceNo),
|
}
|
||||||
'answercontainer',
|
|
||||||
);
|
|
||||||
drag.classList.add('unplaced');
|
|
||||||
} else {
|
} else {
|
||||||
// Get the drop zone position.
|
// Get the drop zone position.
|
||||||
position = CoreDomUtils.getElementXY(
|
const dropZone = this.container.querySelector<HTMLElement>(this.selectors.dropForPlace(placeNo));
|
||||||
this.container,
|
if (dropZone) {
|
||||||
this.selectors.dropForPlace(placeNo),
|
position = CoreDomUtils.getRelativeElementPosition(dropZone, parent);
|
||||||
'addon-qtype-ddwtos-container',
|
// Avoid the border.
|
||||||
);
|
position.x++;
|
||||||
drag.classList.remove('unplaced');
|
position.y++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
drag.classList.toggle('unplaced', !placeNo);
|
||||||
|
|
||||||
if (position) {
|
if (position) {
|
||||||
drag.style.left = position[0] + 'px';
|
drag.style.left = position.x + 'px';
|
||||||
drag.style.top = position[1] + 'px';
|
drag.style.top = position.y + 'px';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -720,50 +720,35 @@ export class CoreDomUtilsProvider {
|
||||||
/**
|
/**
|
||||||
* Retrieve the position of a element relative to another element.
|
* Retrieve the position of a element relative to another element.
|
||||||
*
|
*
|
||||||
* @param container Element to search in.
|
* @param element Element to search in.
|
||||||
* @param selector Selector to find the element to gets the position.
|
* @param selector Selector to find the element to gets the position.
|
||||||
* @param positionParentClass Parent Class where to stop calculating the position. Default inner-scroll.
|
* @param positionParentClass Parent Class where to stop calculating the position. Default inner-scroll.
|
||||||
* @return positionLeft, positionTop of the element relative to.
|
* @return positionLeft, positionTop of the element relative to.
|
||||||
|
* @deprecated since app 4.0. Use getRelativeElementPosition instead.
|
||||||
*/
|
*/
|
||||||
getElementXY(container: HTMLElement, selector?: undefined, positionParentClass?: string): number[];
|
getElementXY(element: HTMLElement, selector?: string, positionParentClass = 'inner-scroll'): [number, number] | null {
|
||||||
getElementXY(container: HTMLElement, selector: string, positionParentClass?: string): number[] | null;
|
if (selector) {
|
||||||
getElementXY(container: HTMLElement, selector?: string, positionParentClass = 'inner-scroll'): number[] | null {
|
const foundElement = element.querySelector<HTMLElement>(selector);
|
||||||
let element = (selector ? container.querySelector<HTMLElement>(selector) : container);
|
if (!foundElement) {
|
||||||
if (!element) {
|
// Element not found.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let positionTop = 0;
|
element = foundElement;
|
||||||
let positionLeft = 0;
|
|
||||||
|
|
||||||
if (!positionParentClass) {
|
|
||||||
positionParentClass = 'inner-scroll';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (element) {
|
const parent = element.closest<HTMLElement>(`.${positionParentClass}`);
|
||||||
positionLeft += (element.offsetLeft - element.scrollLeft + element.clientLeft);
|
if (!parent) {
|
||||||
positionTop += (element.offsetTop - element.scrollTop + element.clientTop);
|
return null;
|
||||||
|
|
||||||
const offsetElement = element.offsetParent;
|
|
||||||
element = element.parentElement;
|
|
||||||
|
|
||||||
// Every parent class has to be checked but the position has to be got form offsetParent.
|
|
||||||
while (offsetElement != element && element) {
|
|
||||||
// If positionParentClass element is reached, stop adding tops.
|
|
||||||
if (element.className.indexOf(positionParentClass) != -1) {
|
|
||||||
element = null;
|
|
||||||
} else {
|
|
||||||
element = element.parentElement;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, check again.
|
const position = CoreDomUtils.getRelativeElementPosition(element, parent);
|
||||||
if (element?.className.indexOf(positionParentClass) != -1) {
|
|
||||||
element = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return [positionLeft, positionTop];
|
// Calculate the top and left positions.
|
||||||
|
return [
|
||||||
|
Math.ceil(position.x),
|
||||||
|
Math.ceil(position.y),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -773,12 +758,12 @@ export class CoreDomUtilsProvider {
|
||||||
* @param parent Parent element to get relative position.
|
* @param parent Parent element to get relative position.
|
||||||
* @return X and Y position.
|
* @return X and Y position.
|
||||||
*/
|
*/
|
||||||
getRelativeElementPosition(element: HTMLElement, parent: HTMLElement): { x: number; y: number} {
|
getRelativeElementPosition(element: HTMLElement, parent: HTMLElement): CoreCoordinates {
|
||||||
// Get the top, left coordinates of two elements
|
// Get the top, left coordinates of two elements
|
||||||
const elementRectangle = element.getBoundingClientRect();
|
const elementRectangle = element.getBoundingClientRect();
|
||||||
const parentRectangle = parent.getBoundingClientRect();
|
const parentRectangle = parent.getBoundingClientRect();
|
||||||
|
|
||||||
// Calculate the top and left positions
|
// Calculate the top and left positions.
|
||||||
return {
|
return {
|
||||||
x: elementRectangle.x - parentRectangle.x,
|
x: elementRectangle.x - parentRectangle.x,
|
||||||
y: elementRectangle.y - parentRectangle.y,
|
y: elementRectangle.y - parentRectangle.y,
|
||||||
|
@ -2442,3 +2427,11 @@ export enum VerticalPoint {
|
||||||
MID = 'mid',
|
MID = 'mid',
|
||||||
BOTTOM = 'bottom',
|
BOTTOM = 'bottom',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Coordinates of an element.
|
||||||
|
*/
|
||||||
|
export type CoreCoordinates = {
|
||||||
|
x: number; // X axis coordinates.
|
||||||
|
y: number; // Y axis coordinates.
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue