From 572912962b1b3db1a2c07c55144364caf8232adf Mon Sep 17 00:00:00 2001 From: Daniel Popescu Date: Thu, 31 Oct 2024 17:49:38 +0200 Subject: [PATCH] [PDCL-12744] Implement move action (#1207) * [PDCL-12744] Implement move action * Coerce css value to string before calling endsWith --------- Co-authored-by: jonsnyder --- bundlesize.json | 12 ++++---- .../Personalization/dom-actions/dom/util.js | 17 +++++++++++ .../dom-actions/initDomActionsModules.js | 6 ++-- .../Personalization/dom-actions/move.js | 28 ++++++++++++++++++ .../Personalization/dom-actions/resize.js | 28 ++++++++++++++++++ .../dom-actions/dom/util.spec.js | 29 +++++++++++++++++++ .../Personalization/dom-actions/move.spec.js | 25 ++++++++++++++++ .../dom-actions/resize.spec.js | 25 ++++++++++++++++ 8 files changed, 162 insertions(+), 8 deletions(-) create mode 100644 src/components/Personalization/dom-actions/dom/util.js create mode 100644 src/components/Personalization/dom-actions/move.js create mode 100644 src/components/Personalization/dom-actions/resize.js create mode 100644 test/unit/specs/components/Personalization/dom-actions/dom/util.spec.js diff --git a/bundlesize.json b/bundlesize.json index f0e7d56eb..ef5285fa6 100644 --- a/bundlesize.json +++ b/bundlesize.json @@ -5,13 +5,13 @@ "brotiliSize": 133 }, "dist/alloy.js": { - "uncompressedSize": 586693, - "gzippedSize": 89397, - "brotiliSize": 69488 + "uncompressedSize": 587523, + "gzippedSize": 89373, + "brotiliSize": 69477 }, "dist/alloy.min.js": { - "uncompressedSize": 123179, - "gzippedSize": 40743, - "brotiliSize": 35341 + "uncompressedSize": 122642, + "gzippedSize": 40537, + "brotiliSize": 35169 } } \ No newline at end of file diff --git a/src/components/Personalization/dom-actions/dom/util.js b/src/components/Personalization/dom-actions/dom/util.js new file mode 100644 index 000000000..223ef787a --- /dev/null +++ b/src/components/Personalization/dom-actions/dom/util.js @@ -0,0 +1,17 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +export const addPxIfMissing = (value) => { + const hasPx = ("" + value).endsWith("px"); + + return hasPx ? value : `${value}px`; +}; diff --git a/src/components/Personalization/dom-actions/initDomActionsModules.js b/src/components/Personalization/dom-actions/initDomActionsModules.js index 3e633c3fb..dc7b61551 100644 --- a/src/components/Personalization/dom-actions/initDomActionsModules.js +++ b/src/components/Personalization/dom-actions/initDomActionsModules.js @@ -18,12 +18,14 @@ import setText from "./setText.js"; import setAttributes from "./setAttributes.js"; import swapImage from "./swapImage.js"; import setStyles from "./setStyles.js"; +import move from "./move.js"; import rearrangeChildren from "./rearrangeChildren.js"; import insertHtmlAfter from "./insertHtmlAfter.js"; import insertHtmlBefore from "./insertHtmlBefore.js"; import replaceHtml from "./replaceHtml.js"; import appendHtml from "./appendHtml.js"; import collectInteractions from "./collectInteractions.js"; +import resize from "./resize.js"; export const DOM_ACTION_SET_HTML = "setHtml"; export const DOM_ACTION_CUSTOM_CODE = "customCode"; @@ -51,8 +53,8 @@ export default () => { [DOM_ACTION_SET_ATTRIBUTE]: createAction(setAttributes), [DOM_ACTION_SET_IMAGE_SOURCE]: createAction(swapImage), [DOM_ACTION_SET_STYLE]: createAction(setStyles), - [DOM_ACTION_MOVE]: createAction(setStyles), - [DOM_ACTION_RESIZE]: createAction(setStyles), + [DOM_ACTION_MOVE]: createAction(move), + [DOM_ACTION_RESIZE]: createAction(resize), [DOM_ACTION_REARRANGE]: createAction(rearrangeChildren), [DOM_ACTION_REMOVE]: createAction(removeNode), [DOM_ACTION_INSERT_AFTER]: createAction(insertHtmlAfter), diff --git a/src/components/Personalization/dom-actions/move.js b/src/components/Personalization/dom-actions/move.js new file mode 100644 index 000000000..c68a19133 --- /dev/null +++ b/src/components/Personalization/dom-actions/move.js @@ -0,0 +1,28 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +import { setStyle } from "./dom/index.js"; +import { addPxIfMissing } from "./dom/util.js"; + +export default (container, styles, decorateProposition) => { + const { priority, ...style } = styles; + + Object.keys(style).forEach((key) => { + let value = style[key]; + if (key === "left" || key === "top") { + value = addPxIfMissing(value); + } + setStyle(container, key, value, priority); + }); + + decorateProposition(container); +}; diff --git a/src/components/Personalization/dom-actions/resize.js b/src/components/Personalization/dom-actions/resize.js new file mode 100644 index 000000000..27bbb926c --- /dev/null +++ b/src/components/Personalization/dom-actions/resize.js @@ -0,0 +1,28 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +import { setStyle } from "./dom/index.js"; +import { addPxIfMissing } from "./dom/util.js"; + +export default (container, styles, decorateProposition) => { + const { priority, ...style } = styles; + + Object.keys(style).forEach((key) => { + let value = style[key]; + if (key === "width" || key === "height") { + value = addPxIfMissing(value); + } + setStyle(container, key, value, priority); + }); + + decorateProposition(container); +}; diff --git a/test/unit/specs/components/Personalization/dom-actions/dom/util.spec.js b/test/unit/specs/components/Personalization/dom-actions/dom/util.spec.js new file mode 100644 index 000000000..35ed66f8e --- /dev/null +++ b/test/unit/specs/components/Personalization/dom-actions/dom/util.spec.js @@ -0,0 +1,29 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +import { addPxIfMissing } from "../../../../../../../src/components/Personalization/dom-actions/dom/util.js"; + +describe("Personalization::DOM::util", () => { + it("appends 'px' string if missing", () => { + const value = "400"; + const result = addPxIfMissing(value); + + expect(result).toEqual("400px"); + }); + + it("does not append 'px' string if already present", () => { + const value = "400px"; + const result = addPxIfMissing(value); + + expect(result).toEqual("400px"); + }); +}); diff --git a/test/unit/specs/components/Personalization/dom-actions/move.spec.js b/test/unit/specs/components/Personalization/dom-actions/move.spec.js index b3ce08d94..7547427c0 100644 --- a/test/unit/specs/components/Personalization/dom-actions/move.spec.js +++ b/test/unit/specs/components/Personalization/dom-actions/move.spec.js @@ -61,4 +61,29 @@ describe("Personalization::actions::move", () => { expect(getAttribute(element, INTERACT_ID_DATA_ATTRIBUTE)).not.toBeNull(); }); }); + + it("should move personalized content even if coordinates are not properly formatted", () => { + const modules = initDomActionsModules(); + const { move } = modules; + const element = createNode("div", { id: "move" }); + + appendNode(document.body, element); + + const settings = { + selector: "#move", + prehidingSelector: "#move", + content: { left: "100", top: "100" }, + meta: { a: 1 }, + }; + + move(settings, decorateProposition).then(() => { + expect(element.style.left).toEqual("100px"); + expect(element.style.top).toEqual("100px"); + + expect(getAttribute(element, CLICK_LABEL_DATA_ATTRIBUTE)).toEqual( + "trackingLabel", + ); + expect(getAttribute(element, INTERACT_ID_DATA_ATTRIBUTE)).not.toBeNull(); + }); + }); }); diff --git a/test/unit/specs/components/Personalization/dom-actions/resize.spec.js b/test/unit/specs/components/Personalization/dom-actions/resize.spec.js index 99e39689c..f212bd18b 100644 --- a/test/unit/specs/components/Personalization/dom-actions/resize.spec.js +++ b/test/unit/specs/components/Personalization/dom-actions/resize.spec.js @@ -61,4 +61,29 @@ describe("Personalization::actions::resize", () => { expect(getAttribute(element, INTERACT_ID_DATA_ATTRIBUTE)).not.toBeNull(); }); }); + + it("should resize personalized content even if dimensions are not properly formatted", () => { + const modules = initDomActionsModules(); + const { resize } = modules; + const element = createNode("div", { id: "resize" }); + + appendNode(document.body, element); + + const settings = { + selector: "#resize", + prehidingSelector: "#resize", + content: { width: "100", height: "100" }, + meta: { a: 1 }, + }; + + return resize(settings, decorateProposition).then(() => { + expect(element.style.width).toEqual("100px"); + expect(element.style.height).toEqual("100px"); + + expect(getAttribute(element, CLICK_LABEL_DATA_ATTRIBUTE)).toEqual( + "trackingLabel", + ); + expect(getAttribute(element, INTERACT_ID_DATA_ATTRIBUTE)).not.toBeNull(); + }); + }); });