diff --git a/src/managers/tagManager/page/TagManager.ts b/src/managers/tagManager/page/TagManager.ts index 171abb45f..511f554f2 100644 --- a/src/managers/tagManager/page/TagManager.ts +++ b/src/managers/tagManager/page/TagManager.ts @@ -34,6 +34,7 @@ export default class TagManager implements ITagManager { // no change detected, return {} return finalTagsObject; } + /** * @param {TagsObject} tags - values of type "boolean" * @returns void @@ -41,6 +42,7 @@ export default class TagManager implements ITagManager { storeTagValuesToUpdate(tags: TagsObjectWithBoolean): void { this.tagsFromTaggingContainer = tags; } + /** * @param {TagsObject} remoteTags - values of type "number" * @returns void diff --git a/src/slidedown/Slidedown.ts b/src/slidedown/Slidedown.ts index 89e9025ef..35e3f7e6b 100755 --- a/src/slidedown/Slidedown.ts +++ b/src/slidedown/Slidedown.ts @@ -15,10 +15,10 @@ import { SlidedownPermissionMessageOptions } from '../models/Prompts'; import { SERVER_CONFIG_DEFAULTS_SLIDEDOWN } from '../config'; import { getLoadingIndicatorWithColor } from './LoadingIndicator'; import { getRetryIndicator } from './RetryIndicator'; -import { SlidedownCssClasses, SlidedownCssIds, COLORS } from "./constants"; +import { SLIDEDOWN_CSS_CLASSES, SLIDEDOWN_CSS_IDS, COLORS } from "./constants"; import { Categories } from '../../src/models/Tags'; import Log from '../../src/libraries/Log'; -import { getSlidedownHtml } from './SlidedownHtml'; +import { getSlidedownElement } from './SlidedownElement'; export default class Slidedown { public options: SlidedownPermissionMessageOptions; @@ -59,7 +59,7 @@ export default class Slidedown { } } - async create(isInUpdateMode?: boolean) { + async create(isInUpdateMode?: boolean): Promise { // TODO: dynamically change btns depending on if its first or repeat display of slidedown (subscribe vs update) if (this.notificationIcons === null) { const icons = await MainHelper.getNotificationIcons(); @@ -67,8 +67,8 @@ export default class Slidedown { this.notificationIcons = icons; // Remove any existing container - if (this.container.className.includes(SlidedownCssClasses.container)) { - removeDomElement(`#${SlidedownCssIds.container}`); + if (this.container.className.includes(SLIDEDOWN_CSS_CLASSES.container)) { + removeDomElement(`#${SLIDEDOWN_CSS_IDS.container}`); } const positiveButtonText = isInUpdateMode && !!this.categoryOptions ? this.categoryOptions.positiveUpdateButton : this.options.acceptButtonText; @@ -78,22 +78,30 @@ export default class Slidedown { this.categoryOptions.updateMessage : this.options.actionMessage; const icon = this.getPlatformNotificationIcon(); - const slidedownHtml = getSlidedownHtml({ + const slidedownElement = getSlidedownElement({ messageText, icon, positiveButtonText, negativeButtonText }); + const slidedownContainer = document.createElement("div"); + const dialogContainer = document.createElement("div"); + // Insert the container - addDomElement('body', 'beforeend', `
`); + slidedownContainer.id = SLIDEDOWN_CSS_IDS.container; + addCssClass(slidedownContainer, SLIDEDOWN_CSS_CLASSES.container); + addCssClass(slidedownContainer, SLIDEDOWN_CSS_CLASSES.reset); + getDomElementOrStub('body').appendChild(slidedownContainer); + // Insert the dialog - addDomElement(this.container, 'beforeend', - `
${slidedownHtml}
`); + dialogContainer.id = SLIDEDOWN_CSS_IDS.dialog; + addCssClass(dialogContainer, SLIDEDOWN_CSS_CLASSES.dialog); + dialogContainer.appendChild(slidedownElement); + this.container.appendChild(dialogContainer); // Animate it in depending on environment - addCssClass(this.container, bowser.mobile ? 'slide-up' : 'slide-down'); + addCssClass(this.container, bowser.mobile ? SLIDEDOWN_CSS_CLASSES.slideUp : SLIDEDOWN_CSS_CLASSES.slideDown); // Add click event handlers this.allowButton.addEventListener('click', this.onSlidedownAllowed.bind(this)); @@ -102,22 +110,22 @@ export default class Slidedown { } } - async onSlidedownAllowed(_: any) { + async onSlidedownAllowed(_: any): Promise { await Event.trigger(Slidedown.EVENTS.ALLOW_CLICK); } - onSlidedownCanceled(_: any) { + onSlidedownCanceled(_: any): void { Event.trigger(Slidedown.EVENTS.CANCEL_CLICK); this.close(); } - close() { - addCssClass(this.container, 'close-slidedown'); + close(): void { + addCssClass(this.container, SLIDEDOWN_CSS_CLASSES.closeSlidedown); once(this.dialog, 'animationend', (event: any, destroyListenerFn: () => void) => { if (event.target === this.dialog && (event.animationName === 'slideDownExit' || event.animationName === 'slideUpExit')) { // Uninstall the event listener for animationend - removeDomElement(`#${SlidedownCssIds.container}`); + removeDomElement(`#${SLIDEDOWN_CSS_IDS.container}`); destroyListenerFn(); Event.trigger(Slidedown.EVENTS.CLOSED); } @@ -127,7 +135,7 @@ export default class Slidedown { /** * only used with Category Slidedown */ - setSaveState(state: boolean) { + setSaveState(state: boolean): void { if (!this.categoryOptions) { Log.debug("Slidedown private category options are not defined"); return; @@ -135,23 +143,26 @@ export default class Slidedown { if (state) { // note: savingButtonText is hardcoded in constructor. TODO: pull from config & set defaults for future release - this.allowButton.innerHTML = this.getIndicatorHolderHtmlWithText(this.categoryOptions!.savingButtonText!); - addDomElement(this.buttonIndicatorHolder, 'beforeend', - getLoadingIndicatorWithColor(COLORS.whiteLoadingIndicator)); this.allowButton.disabled = true; + this.allowButton.textContent = null; + + this.allowButton.insertAdjacentElement('beforeend', this.getTextSpan(this.categoryOptions.savingButtonText)); + this.allowButton.insertAdjacentElement('beforeend', this.getIndicatorHolder()); + + addDomElement(this.buttonIndicatorHolder,'beforeend', getLoadingIndicatorWithColor(COLORS.whiteLoadingIndicator)); addCssClass(this.allowButton, 'disabled'); - addCssClass(this.allowButton, SlidedownCssClasses.savingStateButton); + addCssClass(this.allowButton, SLIDEDOWN_CSS_CLASSES.savingStateButton); } else { // positiveUpdateButton should be defined as written in MainHelper.getSlidedownPermissionMessageOptions - this.allowButton.innerHTML = this.categoryOptions!.positiveUpdateButton!; - removeDomElement(`#${SlidedownCssClasses.buttonIndicatorHolder}`); + this.allowButton.textContent = this.categoryOptions.positiveUpdateButton; + removeDomElement(`#${SLIDEDOWN_CSS_CLASSES.buttonIndicatorHolder}`); this.allowButton.disabled = false; removeCssClass(this.allowButton, 'disabled'); - removeCssClass(this.allowButton, SlidedownCssClasses.savingStateButton); + removeCssClass(this.allowButton, SLIDEDOWN_CSS_CLASSES.savingStateButton); } } - setFailureState(state: boolean) { + setFailureState(state: boolean): void { if (!this.categoryOptions) { Log.debug("Slidedown private category options are not defined"); return; @@ -159,13 +170,17 @@ export default class Slidedown { if (state) { // note: errorButtonText is hardcoded in constructor. TODO: pull from config & set defaults for future release - this.allowButton.innerHTML = this.getIndicatorHolderHtmlWithText(this.categoryOptions!.errorButtonText); + this.allowButton.textContent = null; + this.allowButton.insertAdjacentElement('beforeend', this.getTextSpan(this.categoryOptions.errorButtonText)); + this.allowButton.insertAdjacentElement('beforeend', this.getIndicatorHolder()); + addDomElement(this.buttonIndicatorHolder, 'beforeend', getRetryIndicator()); addCssClass(this.allowButton, 'onesignal-error-state-button'); } else { removeDomElement('#onesignal-button-indicator-holder'); removeCssClass(this.allowButton, 'onesignal-error-state-button'); } + this.isShowingFailureState = state; } @@ -173,37 +188,45 @@ export default class Slidedown { return getPlatformNotificationIcon(this.notificationIcons); } - getIndicatorHolderHtmlWithText(text: string) { - return `${text}
`; + getIndicatorHolder(): Element { + const indicatorHolder = document.createElement("div"); + indicatorHolder.id = SLIDEDOWN_CSS_IDS.buttonIndicatorHolder; + addCssClass(indicatorHolder, SLIDEDOWN_CSS_CLASSES.buttonIndicatorHolder); + return indicatorHolder; + } + + getTextSpan(text: string): Element { + const textHolder = document.createElement("span"); + textHolder.textContent = text; + return textHolder; } get container() { - return getDomElementOrStub(`#${SlidedownCssIds.container}`); + return getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.container}`); } get dialog() { - return getDomElementOrStub(`#${SlidedownCssIds.dialog}`); + return getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.dialog}`); } get allowButton() { - return getDomElementOrStub(`#${SlidedownCssIds.allowButton}`) as HTMLButtonElement; + return getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.allowButton}`) as HTMLButtonElement; } get cancelButton() { - return getDomElementOrStub(`#${SlidedownCssIds.cancelButton}`) as HTMLButtonElement; + return getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.cancelButton}`) as HTMLButtonElement; } get buttonIndicatorHolder() { - return getDomElementOrStub(`#${SlidedownCssIds.buttonIndicatorHolder}`); + return getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.buttonIndicatorHolder}`); } get slidedownFooter() { - return getDomElementOrStub(`#${SlidedownCssIds.footer}`); + return getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.footer}`); } } -export function manageNotifyButtonStateWhileSlidedownShows() { +export function manageNotifyButtonStateWhileSlidedownShows(): void { const notifyButton = OneSignal.notifyButton; if (notifyButton && notifyButton.options.enable && diff --git a/src/slidedown/SlidedownElement.ts b/src/slidedown/SlidedownElement.ts new file mode 100644 index 000000000..498bdfe32 --- /dev/null +++ b/src/slidedown/SlidedownElement.ts @@ -0,0 +1,69 @@ +import { SlidedownHtmlProps } from "./types"; +import { DEFAULT_ICON, SLIDEDOWN_CSS_IDS, SLIDEDOWN_CSS_CLASSES, SLIDEDOWN_BUTTON_CLASSES } from "./constants"; +import { addCssClass } from '../../src/utils'; + +export function getSlidedownElement(dialogProps: SlidedownHtmlProps): Element { + const { icon, messageText, positiveButtonText, negativeButtonText } = dialogProps; + + const finalIcon = icon === SLIDEDOWN_CSS_CLASSES.defaultIcon ? DEFAULT_ICON : icon; + const finalIconClass = icon === SLIDEDOWN_CSS_CLASSES.defaultIcon ? SLIDEDOWN_CSS_CLASSES.defaultIcon : ''; + + const normalSlidedown = document.createElement("div"); + const slidedownBody = document.createElement("div"); + const bodyMessage = document.createElement("div"); + const slidedownBodyIcon = document.createElement("div"); + const loadingContainer = document.createElement("div"); + const slidedownFooter = document.createElement("div"); + const positiveButton = document.createElement("button"); + const negativeButton = document.createElement("button"); + const clearfix = document.createElement("div"); + const clearfix2 = document.createElement("div"); + const image = document.createElement("img"); + + addCssClass(slidedownBody, SLIDEDOWN_CSS_CLASSES.body); + addCssClass(slidedownBodyIcon, SLIDEDOWN_CSS_CLASSES.icon); + addCssClass(bodyMessage, SLIDEDOWN_CSS_CLASSES.message); + addCssClass(slidedownFooter, SLIDEDOWN_CSS_CLASSES.footer); + addCssClass(clearfix, SLIDEDOWN_CSS_CLASSES.clearfix); + addCssClass(clearfix2, SLIDEDOWN_CSS_CLASSES.clearfix); + addCssClass(positiveButton, SLIDEDOWN_BUTTON_CLASSES.alignRight); + addCssClass(positiveButton, SLIDEDOWN_BUTTON_CLASSES.primary); + addCssClass(positiveButton, SLIDEDOWN_BUTTON_CLASSES.slidedownButton); + addCssClass(negativeButton, SLIDEDOWN_BUTTON_CLASSES.alignRight); + addCssClass(negativeButton, SLIDEDOWN_BUTTON_CLASSES.secondary); + addCssClass(negativeButton, SLIDEDOWN_BUTTON_CLASSES.slidedownButton); + + normalSlidedown.id = SLIDEDOWN_CSS_IDS.normalSlidedown; + slidedownBody.id = SLIDEDOWN_CSS_IDS.body; + loadingContainer.id = SLIDEDOWN_CSS_IDS.loadingContainer; + positiveButton.id = SLIDEDOWN_CSS_IDS.allowButton; + negativeButton.id = SLIDEDOWN_CSS_IDS.cancelButton; + slidedownFooter.id = SLIDEDOWN_CSS_IDS.footer; + + if (finalIconClass) { + addCssClass(image, finalIconClass); + } + + image.setAttribute("alt", "notification icon"); + image.setAttribute("src", finalIcon || ''); + + bodyMessage.innerText = messageText || ''; + positiveButton.innerText = positiveButtonText || ''; + negativeButton.innerText = negativeButtonText || ''; + + slidedownBodyIcon.appendChild(image); + + slidedownBody.appendChild(slidedownBodyIcon); + slidedownBody.appendChild(bodyMessage); + slidedownBody.appendChild(clearfix); + slidedownBody.appendChild(loadingContainer); + + slidedownFooter.appendChild(positiveButton); + slidedownFooter.appendChild(negativeButton); + slidedownFooter.appendChild(clearfix2); + + normalSlidedown.appendChild(slidedownBody); + normalSlidedown.appendChild(slidedownFooter); + + return normalSlidedown; +} diff --git a/src/slidedown/SlidedownHtml.ts b/src/slidedown/SlidedownHtml.ts deleted file mode 100644 index 3f60c947b..000000000 --- a/src/slidedown/SlidedownHtml.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { SlidedownHtmlProps } from "./types"; -import { DEFAULT_ICON } from "./constants"; - -export function getSlidedownHtml(dialogProps: SlidedownHtmlProps): string { - const { icon, messageText, positiveButtonText, negativeButtonText } = dialogProps; - - const finalIcon = icon === 'default-icon' ? DEFAULT_ICON : icon; - const finalIconClass = icon === 'default-icon' ? 'default-icon' : ''; - - return `` + - `
` + - `
` + - `
` + - `notification icon` + - `
` + - `
${messageText}
` + - `
` + - `
` + - `
` + - `` + - `
`; -} diff --git a/src/slidedown/TaggingContainer.ts b/src/slidedown/TaggingContainer.ts index 13c0ada89..0a1760740 100644 --- a/src/slidedown/TaggingContainer.ts +++ b/src/slidedown/TaggingContainer.ts @@ -8,89 +8,121 @@ import { } from '../utils'; import { getLoadingIndicatorWithColor } from './LoadingIndicator'; import { - SlidedownCssIds, - TaggingContainerCssClasses, - TaggingContainerCssIds, - TaggingContainerStrings, - COLORS + SLIDEDOWN_CSS_IDS, + TAGGING_CONTAINER_CSS_CLASSES, + TAGGING_CONTAINER_CSS_IDS, + TAGGING_CONTAINER_STRINGS, + COLORS, + SLIDEDOWN_CSS_CLASSES } from './constants'; import TagUtils from '../../src/utils/TagUtils'; export default class TaggingContainer { - private html: string = ""; public mount(remoteTagCategories: Array, existingPlayerTags?: TagsObjectWithBoolean): void { - this.html = this.generateHtml(remoteTagCategories, existingPlayerTags); + const taggingContainer = this.generateHtml(remoteTagCategories, existingPlayerTags); - const body = getDomElementOrStub(`#${SlidedownCssIds.body}`); - addDomElement(body, 'beforeend', this.html); + const body = getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.body}`); + body.appendChild(taggingContainer); if (this.taggingContainer) { - // TODO: is there unmount and remove this listener? this.taggingContainer.addEventListener('change', this.toggleCheckedTag); } - const allowButton = getDomElementOrStub(`#${SlidedownCssIds.allowButton}`) as HTMLButtonElement; + const allowButton = getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.allowButton}`) as HTMLButtonElement; allowButton.disabled = false; - removeCssClass(allowButton, 'disabled'); - removeDomElement(`#${TaggingContainerCssClasses.loadingContainer}`); + removeCssClass(allowButton, 'disabled'); + removeDomElement(`#${SLIDEDOWN_CSS_IDS.loadingContainer}`); } public load(): void { - const loadingContainer = getDomElementOrStub(`#${TaggingContainerCssIds.loadingContainer}`); - addCssClass(loadingContainer, `${TaggingContainerCssClasses.loadingContainer}`); + const loadingContainer = getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.loadingContainer}`); + const allowButton = getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.allowButton}`) as HTMLButtonElement; + const loadingMessageContainer = document.createElement("div"); + + addCssClass(loadingContainer, `${SLIDEDOWN_CSS_CLASSES.loadingContainer}`); + addCssClass(loadingMessageContainer, TAGGING_CONTAINER_CSS_CLASSES.loadingMessage); + addCssClass(allowButton, 'disabled'); + addDomElement(loadingContainer, 'beforeend', getLoadingIndicatorWithColor(COLORS.greyLoadingIndicator)); - addDomElement(loadingContainer, 'beforeend', `
` + - `${TaggingContainerStrings.fetchingPreferences}
`); - const allowButton = getDomElementOrStub(`#${SlidedownCssIds.allowButton}`) as HTMLButtonElement; + loadingMessageContainer.innerText = TAGGING_CONTAINER_STRINGS.fetchingPreferences; + loadingContainer.appendChild(loadingMessageContainer); allowButton.disabled = true; - addCssClass(allowButton, 'disabled'); } - private generateHtml(remoteTagCategories: TagCategory[], existingPlayerTags?: TagsObjectWithBoolean): string { + private generateHtml(remoteTagCategories: TagCategory[], existingPlayerTags?: TagsObjectWithBoolean): Element { const checkedTagCategories = TagUtils.getCheckedTagCategories(remoteTagCategories, existingPlayerTags); - const firstColumnArr = checkedTagCategories.filter(elem => checkedTagCategories.indexOf(elem) % 2 === 0); + + const firstColumnArr = checkedTagCategories.filter(elem => checkedTagCategories.indexOf(elem) % 2 === 0); const secondColumnArr = checkedTagCategories.filter(elem => checkedTagCategories.indexOf(elem) % 2); - let innerHtml = `
`; + const firstColumnContainer = document.createElement("div"); + const secondColumnContainer = document.createElement("div"); + const taggingContainer = document.createElement("div"); + + addCssClass(firstColumnContainer, TAGGING_CONTAINER_CSS_CLASSES.taggingContainerCol); + addCssClass(secondColumnContainer, TAGGING_CONTAINER_CSS_CLASSES.taggingContainerCol); + addCssClass(taggingContainer, TAGGING_CONTAINER_CSS_CLASSES.taggingContainer); + + taggingContainer.id = TAGGING_CONTAINER_CSS_IDS.taggingContainer; + firstColumnArr.forEach(elem => { - innerHtml += this.getCategoryLabelHtml(elem); + firstColumnContainer.appendChild(this.getCategoryLabelElement(elem)); }); - innerHtml += "
"; - innerHtml += `
`; secondColumnArr.forEach(elem => { - innerHtml += this.getCategoryLabelHtml(elem); + secondColumnContainer.appendChild(this.getCategoryLabelElement(elem)); }); - innerHtml += "
"; - return `
${innerHtml}
`; + taggingContainer.appendChild(firstColumnContainer); + taggingContainer.appendChild(secondColumnContainer); + + return taggingContainer; } - private getCategoryLabelHtml(tagCategory: TagCategory): string { + private getCategoryLabelElement(tagCategory: TagCategory): Element { const { label } = tagCategory; - return ` - -
`; + + const labelElement = document.createElement("label"); + const labelSpan = document.createElement("span"); + const inputElement = document.createElement("input"); + const checkmarkSpan = document.createElement("span"); + const clear = document.createElement("div"); + const wrappingDiv = document.createElement("div"); + + addCssClass(labelElement, TAGGING_CONTAINER_CSS_CLASSES.categoryLabel); + addCssClass(labelSpan, TAGGING_CONTAINER_CSS_CLASSES.categoryLabelText); + addCssClass(inputElement, TAGGING_CONTAINER_CSS_CLASSES.categoryLabelInput); + addCssClass(checkmarkSpan, TAGGING_CONTAINER_CSS_CLASSES.checkmark); + + labelElement.title = label; + labelSpan.innerText = label; + inputElement.type = "checkbox"; + inputElement.value = tagCategory.tag; + inputElement.checked = !!tagCategory.checked; + + labelElement.appendChild(labelSpan); + labelElement.appendChild(inputElement); + labelElement.appendChild(checkmarkSpan); + + clear.setAttribute("style", "clear:both"); + + wrappingDiv.appendChild(labelElement); + wrappingDiv.appendChild(clear); + + return wrappingDiv; } private get taggingContainer(): Element { - return getDomElementOrStub(`#${SlidedownCssIds.body} > div.${TaggingContainerCssClasses.taggingContainer}`); + const selector = `#${SLIDEDOWN_CSS_IDS.body} > div.${TAGGING_CONTAINER_CSS_CLASSES.taggingContainer}`; + return getDomElementOrStub(selector); } private toggleCheckedTag(e: Event): void { const target = (e.target); + if (target && target.getAttribute("type") === "checkbox") { const isChecked = target.checked; target.setAttribute("checked", isChecked.toString()); @@ -98,12 +130,13 @@ export default class TaggingContainer { } static getValuesFromTaggingContainer(): TagsObjectWithBoolean { - const selector = `#${SlidedownCssIds.body} > div.${TaggingContainerCssClasses.taggingContainer}` + - `> div > label > input[type=checkbox]`; + const selector = `#${SLIDEDOWN_CSS_IDS.body} > div.${TAGGING_CONTAINER_CSS_CLASSES.taggingContainer}` + + `> div > div > label > input[type=checkbox]`; const inputNodeArr = document.querySelectorAll(selector); const tags: TagsObjectWithBoolean = {}; + inputNodeArr.forEach(node => { - tags[(node).defaultValue] = (node).checked; + tags[(node).value] = (node).checked; }); return tags; } diff --git a/src/slidedown/constants.ts b/src/slidedown/constants.ts index 428c9a2c3..ac47dcd50 100644 --- a/src/slidedown/constants.ts +++ b/src/slidedown/constants.ts @@ -1,4 +1,4 @@ -export const SlidedownCssClasses = { +export const SLIDEDOWN_CSS_CLASSES = { allowButton: "onesignal-slidedown-allow-button", body: "slidedown-body", buttonIndicatorHolder: "onesignal-button-indicator-holder", @@ -7,10 +7,18 @@ export const SlidedownCssClasses = { dialog: "onesignal-slidedown-dialog", footer: "slidedown-footer", reset: "onesignal-reset", - savingStateButton: "onesignal-saving-state-button" + savingStateButton: "onesignal-saving-state-button", + slideUp: 'slide-up', + slideDown: 'slide-down', + closeSlidedown: 'close-slidedown', + icon: 'slidedown-body-icon', + message: 'slidedown-body-message', + defaultIcon: 'default-icon', + loadingContainer: "onesignal-loading-container", + clearfix: "clearfix" }; -export const SlidedownCssIds = { +export const SLIDEDOWN_CSS_IDS = { allowButton: "onesignal-slidedown-allow-button", body: "slidedown-body", buttonIndicatorHolder: "onesignal-button-indicator-holder", @@ -18,21 +26,28 @@ export const SlidedownCssIds = { container: "onesignal-slidedown-container", dialog: "onesignal-slidedown-dialog", footer: "slidedown-footer", + normalSlidedown: "normal-slidedown", + loadingContainer: "onesignal-loading-container", +}; + +export const SLIDEDOWN_BUTTON_CLASSES = { + alignRight: 'align-right', + primary: 'primary', + secondary: 'secondary', + slidedownButton: 'slidedown-button' }; -export const TaggingContainerCssClasses = { +export const TAGGING_CONTAINER_CSS_CLASSES = { categoryLabelInput: "onesignal-category-label-input", categoryLabelText: "onesignal-category-label-text", categoryLabel: "onesignal-category-label", checkmark: "onesignal-checkmark", taggingContainer: "tagging-container", taggingContainerCol: "tagging-container-col", - loadingContainer: "onesignal-loading-container", loadingMessage: "onesignal-loading-message" }; -export const TaggingContainerCssIds = { - loadingContainer: "onesignal-loading-container", +export const TAGGING_CONTAINER_CSS_IDS = { taggingContainer: "tagging-container", }; @@ -50,6 +65,6 @@ export const COLORS = { whiteLoadingIndicator: "#FFFFFF" }; -export const TaggingContainerStrings = { +export const TAGGING_CONTAINER_STRINGS = { fetchingPreferences : "Fetching your preferences" }; diff --git a/src/stylesheets/slidedown.scss b/src/stylesheets/slidedown.scss index 36aa67933..646487818 100755 --- a/src/stylesheets/slidedown.scss +++ b/src/stylesheets/slidedown.scss @@ -324,12 +324,17 @@ $border-radius: 0.5em; background: #E54A4D; transition: linear 75ms; align-items: center; + + span { + cursor: pointer; + } } } &.onesignal-button-indicator-holder { display: flex; margin-left: 0.5em; + cursor: pointer; } &.secondary { diff --git a/test/support/sdk/TestEnvironment.ts b/test/support/sdk/TestEnvironment.ts index 85e702d7d..f185bab54 100644 --- a/test/support/sdk/TestEnvironment.ts +++ b/test/support/sdk/TestEnvironment.ts @@ -41,8 +41,7 @@ import TagManager from '../../../src/managers/tagManager/page/TagManager'; import { DynamicResourceLoader, ResourceLoadState } from '../../../src/services/DynamicResourceLoader'; import { SinonSandbox } from 'sinon'; import { ServiceWorkerManager } from '../../../src/managers/ServiceWorkerManager'; -import { SlidedownCssIds } from '../../../src/slidedown/constants'; -import { getSlidedownHtml } from '../../../src/slidedown/SlidedownHtml'; +import { getSlidedownElement } from '../../../src/slidedown/SlidedownElement'; // NodeJS.Global declare var global: any; @@ -221,13 +220,18 @@ export class TestEnvironment { } let html = ''; + + // global document object must be defined for `getSlidedownElement` to work correctly. + // this line initializes the document object + global.document = jsdom.jsdom(''); + if (config.addPrompts) { html = `\
\
\ \ \ - ${getSlidedownHtml({})}`; + ${getSlidedownElement({}).outerHTML}`; } var windowDef = await new Promise((resolve, reject) => { diff --git a/test/unit/prompts/TaggingContainer.ts b/test/unit/prompts/TaggingContainer.ts index 17b4911bb..e4c49dbdf 100644 --- a/test/unit/prompts/TaggingContainer.ts +++ b/test/unit/prompts/TaggingContainer.ts @@ -5,7 +5,7 @@ import { TestEnvironment, HttpHttpsEnvironment, BrowserUserAgent } from '../../s import { TagsObjectWithBoolean } from '../../../src/models/Tags'; import { getDomElementOrStub } from '../../../src/utils'; import TagUtils from '../../../src/utils/TagUtils'; -import { TaggingContainerCssIds, SlidedownCssClasses } from '../../../src/slidedown/constants'; +import { TAGGING_CONTAINER_CSS_IDS, SLIDEDOWN_CSS_CLASSES, SLIDEDOWN_CSS_IDS } from '../../../src/slidedown/constants'; const sandbox: SinonSandbox = sinon.sandbox.create(); @@ -29,13 +29,13 @@ test.afterEach(function () { test('check that calling mount() adds the tagging container to DOM', t => { const taggingContainer = new TaggingContainer(); const categoryArr = [{ tag: "tag1", label: "label1" }]; - let containerFromDom = getDomElementOrStub(`#${TaggingContainerCssIds.taggingContainer}`); - t.false(containerFromDom.id === TaggingContainerCssIds.taggingContainer); + let containerFromDom = getDomElementOrStub(`#${TAGGING_CONTAINER_CSS_IDS.taggingContainer}`); + t.false(containerFromDom.id === TAGGING_CONTAINER_CSS_IDS.taggingContainer); taggingContainer.mount(categoryArr); - containerFromDom = getDomElementOrStub(`#${TaggingContainerCssIds.taggingContainer}`); - t.true(containerFromDom.id === TaggingContainerCssIds.taggingContainer); + containerFromDom = getDomElementOrStub(`#${TAGGING_CONTAINER_CSS_IDS.taggingContainer}`); + t.true(containerFromDom.id === TAGGING_CONTAINER_CSS_IDS.taggingContainer); }); test('check that calling mount() results in allowButton enabled', t => { @@ -44,19 +44,19 @@ test('check that calling mount() results in allowButton enabled', t => { taggingContainer.mount(categoryArr); - const allowButtonElement = getDomElementOrStub(`#${SlidedownCssClasses.allowButton}`); + const allowButtonElement = getDomElementOrStub(`#${SLIDEDOWN_CSS_CLASSES.allowButton}`); t.false((allowButtonElement).disabled); }); test('check that calling load() adds the loading container to DOM', t => { const taggingContainer = new TaggingContainer(); - let loadingContainer = getDomElementOrStub(`#${TaggingContainerCssIds.loadingContainer}`); + let loadingContainer = getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.loadingContainer}`); t.false(loadingContainer.innerHTML !== ""); t.false(loadingContainer.classList.length > 0); taggingContainer.load(); - loadingContainer = getDomElementOrStub(`#${TaggingContainerCssIds.loadingContainer}`); + loadingContainer = getDomElementOrStub(`#${SLIDEDOWN_CSS_IDS.loadingContainer}`); t.true(loadingContainer.innerHTML !== ""); t.true(loadingContainer.classList.length > 0); });