Advertisement
Guest User

Untitled

a guest
May 27th, 2019
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.61 KB | None | 0 0
  1. import {
  2. Widget,
  3. WidgetInterface
  4. } from '@shop-builder/core/widget';
  5. import { findOneById, findAll, findOneAttributeById } from '@api/services/products';
  6. import { findOneStandardOfVoiceData } from '@api/services/tariff';
  7. import { findOneStandardOfData } from '@api/services/tariff';
  8. import { findOneByComponentSet } from '@api/services/offers';
  9. import { getHexcodeByColor } from '@api/utils';
  10. import { Configurator } from '@api/services/configurator';
  11. import { formatEuro } from '@api/utils';
  12. import { scrollTo } from '@api/utils';
  13. import { preloadImages } from '@api/utils';
  14. import { getWidget } from '@api/utils';
  15. import { DeviceDetailColor } from './device-detail-color';
  16. import { DeviceDetailCapacity } from './device-detail-capacity';
  17. import Flickity from 'flickity';
  18. import { SERVICE_TYPE_PROMO_BUBBLE } from '@api/schema/offer';
  19. import { BUNDLE_DESCRIPTION_ATTRIBUTE } from '@api/schema/product';
  20. import { BasketAssistant } from '@api/services/basket';
  21.  
  22. declare var jQuery: any;
  23.  
  24. @Widget({
  25. name: 'device-detail'
  26. })
  27. export class DeviceDetailWidget {
  28. public getElement: Function;
  29. public product;
  30. public offer;
  31. public topSmartphoneDealElement;
  32. public standardTariff;
  33. public flkty;
  34. public currentSlideIndex: number = 0;
  35. private checkboxTimeout;
  36. private colorComponents: Array<DeviceDetailColor> = [];
  37. private capacityComponents: Array<DeviceDetailCapacity> = [];
  38. private currentImages: string = '';
  39.  
  40. public async didMount (): Promise<void> {
  41. this.showContainer();
  42. await this.loadProduct();
  43. this.registerEventListeners();
  44. }
  45.  
  46. public registerEventListeners () {
  47. this.getElement().querySelector('.tariff-cta').addEventListener('click', scrollTo.bind(null, 'tariff-slider'));
  48.  
  49. this.getElement().querySelector('.more-details').addEventListener('click', (e) => {
  50. e.preventDefault();
  51.  
  52. const widget = getWidget('device-detail-tabs');
  53.  
  54. if (widget) {
  55. widget.switchToTechnicalDetails();
  56. scrollTo('device-detail-tabs');
  57. }
  58.  
  59. });
  60.  
  61. }
  62.  
  63. public async setOffer () {
  64. this.offer = Configurator.getOffer();
  65.  
  66. this.setPrice(this.offer.getOnetimePrice());
  67.  
  68. if (this.product.currentVersionContainsBundle()) {
  69. this.setSubTitle(this.product.getAttributeById(BUNDLE_DESCRIPTION_ATTRIBUTE).value);
  70. } else {
  71. this.setSubTitle('');
  72. }
  73.  
  74. const child = this.product.getCurrentVersion();
  75. const deliveryTime = child.additional.deliveryTime;
  76.  
  77. this.getElement().querySelector('.delivery-time').innerHTML = deliveryTime;
  78.  
  79. if (Configurator.getTariff()) {
  80. const tariff = Configurator.getTariff();
  81.  
  82. this.setWhichTariff(tariff.label);
  83.  
  84. // Check if top smartphone deal is possible with current tariff
  85. if (Configurator.getTariff().topSmartphoneDeals.indexOf(this.product.id) > -1) {
  86. this.showTopSmartphoneDeal();
  87.  
  88. if (!this.product.usesTopSmartphoneDeal() && this.topSmartphoneDealChecked()) {
  89. this.uncheckTopSmartphoneDeal();
  90. }
  91. } else {
  92. this.hideTopSmartphoneDeal();
  93. }
  94. }
  95.  
  96. const promoFlags = this.offer.getServicesByType(SERVICE_TYPE_PROMO_BUBBLE);
  97.  
  98. if (promoFlags.length) {
  99. this.showPromoBubble(promoFlags[promoFlags.length - 1].description.additional.image);
  100. } else {
  101. this.hidePromoBubble();
  102. }
  103.  
  104. this.setPreview();
  105. }
  106.  
  107. public async loadProduct () {
  108. let product = await Configurator.getProduct();
  109. this.product = product;
  110.  
  111. let deviceId = 0;
  112.  
  113. if (product) {
  114. deviceId = product.getId();
  115.  
  116. if (this.product.currentVersionContainsBundle()) {
  117. this.setSubTitle(this.product.getAttributeById(BUNDLE_DESCRIPTION_ATTRIBUTE).value);
  118. } else {
  119. this.setSubTitle('');
  120. }
  121. }
  122.  
  123. if (this.getElement().dataset.device && !Configurator.hasExternalProduct()) {
  124. if (this.getElement().dataset.device.length > 0) {
  125. deviceId = parseInt(this.getElement().dataset.device, 10);
  126. product = await findOneById(deviceId);
  127. await Configurator.setProduct(product);
  128. this.product = product;
  129. }
  130. }
  131.  
  132. if (this.product.getSubsidizedWith() === 'voice') {
  133. this.standardTariff = await findOneStandardOfVoiceData();
  134. } else {
  135. this.standardTariff = await findOneStandardOfData();
  136. }
  137.  
  138. if (Configurator.getOffer()) {
  139. await this.setOffer();
  140. }
  141.  
  142. if (!Configurator.getTariff()) {
  143. await Configurator.setTariff(this.standardTariff);
  144. }
  145.  
  146. if (product.hasTopSmartphoneDeal()) {
  147. this.displayTopSmartphoneDeal();
  148. }
  149.  
  150. if (product.hasTopSmartphoneDeal() && !Configurator.hasExternalProduct()) {
  151. this.setWhichTariff(Configurator.getTariff().label);
  152. this.checkTopSmartphoneDeal();
  153. } else if (product.hasTopSmartphoneDeal()) {
  154. if (product.usesTopSmartphoneDeal()) {
  155. setTimeout(() => {
  156. this.checkTopSmartphoneDeal();
  157. }, 1000);
  158. }
  159. }
  160.  
  161. this.setPreview();
  162. this.setTopFeatures(product.getTopFeatures());
  163.  
  164. if (product.getColors().length > 0) {
  165. await this.setColors(product.getColors(), product.getAllColors());
  166. }
  167.  
  168. if (product.getCapacities().length > 0) {
  169. await this.setCapacities(product.getCapacities(), product.getAllCapacities());
  170. }
  171.  
  172. if (product.getColors().length > 0) {
  173. await this.selectColor(product.getCurrentColor());
  174. }
  175.  
  176. if (product.getColors().length > 0) {
  177. await this.selectCapacity(product.getCurrentCapacity());
  178. }
  179.  
  180. Configurator.subscribe('offerChanged', this.setOffer.bind(this));
  181.  
  182. if (Configurator.getOffer()) {
  183. await this.setOffer();
  184. }
  185.  
  186. setTimeout(() => {
  187. this.show();
  188. }, 250);
  189.  
  190. }
  191.  
  192. public setSubTitle (label: string) {
  193. if (label.length > 0) {
  194. if (this.getElement().querySelector('.title .sub-headline')) {
  195. this.getElement().querySelector('.title .sub-headline').innerHTML = label;
  196. } else {
  197. const subHeadlineElement = document.createElement('h3');
  198.  
  199. subHeadlineElement.className = 'sub-headline loaded';
  200. subHeadlineElement.innerHTML = label;
  201.  
  202. this.getElement().querySelector('.title').appendChild(subHeadlineElement);
  203. }
  204. } else if (this.getElement().querySelector('.title .sub-headline')) {
  205. this.getElement().querySelector('.title .sub-headline').remove();
  206. }
  207. }
  208.  
  209. public async setPreview () {
  210. let images = this.product.getShowcaseImages();
  211.  
  212. if (images.length === 0) {
  213. images = ['https://www.vodafone.de' + this.product.getImages().large];
  214. }
  215.  
  216. if (this.currentImages === JSON.stringify(images)) {
  217. return;
  218. } else {
  219. this.currentImages = JSON.stringify(images);
  220. }
  221.  
  222. const preview = document.createElement('div');
  223. preview.innerHTML = '';
  224. preview.classList.add('product-preview');
  225. preview.classList.add('main-carousel');
  226. preview.dataset.preview = '';
  227. preview.style.opacity = '0';
  228. preview.style.display = 'none';
  229.  
  230. await preloadImages(images);
  231.  
  232. for (const url of images) {
  233. const wrap = document.createElement('div');
  234. wrap.classList.add('carousel-cell');
  235.  
  236. const image = document.createElement('img');
  237.  
  238. image.setAttribute('src', url);
  239. wrap.appendChild(image);
  240.  
  241. preview.appendChild(wrap);
  242. }
  243.  
  244. this.getElement().querySelector('.product-image').innerHTML = '';
  245. this.getElement().querySelector('.product-image').appendChild(preview);
  246.  
  247. this.flkty = new Flickity(preview, {
  248. pageDots: false,
  249. accessibility: false,
  250. resize: true,
  251. wrapAround: true,
  252. cellAlign: 'center',
  253. initialIndex: typeof images[this.currentSlideIndex] !== 'undefined' ? this.currentSlideIndex : 0
  254. });
  255.  
  256. this.flkty.on('change', i => this.currentSlideIndex = i);
  257.  
  258. preview.style.display = 'block';
  259.  
  260. setTimeout(() => {
  261. preview.style.opacity = '1';
  262. this.flkty.resize();
  263. }, 250);
  264. }
  265.  
  266. public async setColors (colors: any, allColors: any) {
  267. const preview = this.getElement()
  268. .querySelector('[data-colorChoices]')
  269. .querySelector('.choices');
  270.  
  271. preview.innerHTML = '';
  272.  
  273. const currentColor = Configurator.getProduct().getCurrentColor();
  274. Configurator.getProduct().stopEventListeners();
  275.  
  276. for (const color of allColors) {
  277.  
  278. const hexcode = getHexcodeByColor(color);
  279. const colorComponent = new DeviceDetailColor(hexcode, color);
  280.  
  281. this.colorComponents.push(colorComponent);
  282.  
  283. if (colors.indexOf(color) > -1) {
  284. Configurator.getProduct().selectColor(color);
  285.  
  286. try {
  287. const sampleOffer = await findOneByComponentSet([this.standardTariff, Configurator.getProduct()]);
  288.  
  289. if (sampleOffer) {
  290. if (color === currentColor) {
  291. colorComponent.activate();
  292. }
  293. }
  294. }
  295.  
  296. catch (e) {
  297. colorComponent.disable();
  298. }
  299. } else {
  300. colorComponent.disable();
  301. }
  302.  
  303. colorComponent.onClick(this.selectColor.bind(this, color));
  304.  
  305. preview.appendChild(colorComponent.render());
  306. }
  307.  
  308. Configurator.getProduct().selectColor(currentColor);
  309. Configurator.getProduct().resumeEventListeners();
  310.  
  311. if (colors.length > 0) {
  312. this.getElement()
  313. .querySelector('[data-colorChoices]')
  314. .className = 'item';
  315.  
  316. this.activateConfiguration();
  317. }
  318. }
  319.  
  320. public async updateColorComponents () {
  321. const currentColor = Configurator.getProduct().getCurrentColor();
  322. Configurator.getProduct().stopEventListeners();
  323.  
  324. for (const colorComponent of this.colorComponents) {
  325. const match = Configurator.getProduct().selectColor(colorComponent.getValue());
  326.  
  327. try {
  328. const sampleOffer = await findOneByComponentSet([this.standardTariff, Configurator.getProduct()]);
  329.  
  330. if (sampleOffer && match) {
  331. if (currentColor === colorComponent.getValue()) {
  332. colorComponent.activate();
  333. } else {
  334. colorComponent.enable();
  335. }
  336. } else {
  337. colorComponent.disable();
  338. }
  339. }
  340.  
  341. catch (e) {
  342. colorComponent.disable();
  343. }
  344. }
  345.  
  346. Configurator.getProduct().selectColor(currentColor);
  347. Configurator.getProduct().resumeEventListeners();
  348. }
  349.  
  350. public async selectColor (color: string) {
  351. let colorElement = this.getElement().querySelector(`[data-color="${color}"]`);
  352.  
  353. if (!colorElement) {
  354. colorElement = this.getElement().querySelectorAll('[data-color]')[0];
  355. color = colorElement.dataset.color;
  356. }
  357.  
  358. if (colorElement.className.indexOf('inactive') > -1) {
  359. return;
  360. }
  361.  
  362. for (const element of this.getElement().querySelectorAll('.color-choice')) {
  363. element.classList.remove('active');
  364. }
  365.  
  366. colorElement.querySelector('.color-choice').className = 'color-choice active';
  367.  
  368. this
  369. .getElement()
  370. .querySelector('[data-colorChoices] .item-title span')
  371. .innerHTML = color;
  372.  
  373. this.product.selectColor(color);
  374.  
  375. this.setPreview();
  376.  
  377. await this.updateCapacityComponents();
  378. }
  379.  
  380. public async setCapacities (capacities: any, allCapacities: any) {
  381. const preview = this.getElement()
  382. .querySelector('[data-capacityChoices]')
  383. .querySelector('.choices');
  384.  
  385. preview.innerHTML = '';
  386.  
  387. const currentCapacity = Configurator.getProduct().getCurrentCapacity();
  388. Configurator.getProduct().stopEventListeners();
  389.  
  390. for (const capacity of allCapacities) {
  391. const capacityComponent = new DeviceDetailCapacity(capacity);
  392.  
  393. this.capacityComponents.push(capacityComponent);
  394.  
  395. if (capacities.indexOf(capacity) > -1) {
  396. Configurator.getProduct().selectCapacity(capacity);
  397.  
  398. try {
  399. const sampleOffer = await findOneByComponentSet([this.standardTariff, Configurator.getProduct()]);
  400.  
  401. if (sampleOffer) {
  402. if (capacity === currentCapacity) {
  403. capacityComponent.activate();
  404. } else {
  405. capacityComponent.enable();
  406. }
  407. } else {
  408. capacityComponent.disable();
  409. }
  410. }
  411.  
  412. catch (e) {
  413. capacityComponent.disable();
  414. }
  415. } else {
  416. capacityComponent.disable();
  417. }
  418.  
  419. capacityComponent.onClick(this.selectCapacity.bind(this, capacity));
  420.  
  421. preview.appendChild(capacityComponent.render());
  422. }
  423.  
  424. Configurator.getProduct().selectCapacity(currentCapacity);
  425. Configurator.getProduct().resumeEventListeners();
  426.  
  427. if (capacities.length > 0) {
  428. this.getElement()
  429. .querySelector('[data-capacityChoices]')
  430. .className = 'item';
  431.  
  432. this.activateConfiguration();
  433. }
  434. }
  435.  
  436. public async updateCapacityComponents () {
  437. const currentCapacity = Configurator.getProduct().getCurrentCapacity();
  438. Configurator.getProduct().stopEventListeners();
  439.  
  440. for (const capacityComponent of this.capacityComponents) {
  441. const match = Configurator.getProduct().selectCapacity(capacityComponent.getCapacity());
  442.  
  443. try {
  444. const sampleOffer = await findOneByComponentSet([this.standardTariff, Configurator.getProduct()]);
  445.  
  446. if (sampleOffer && match) {
  447. if (currentCapacity === capacityComponent.getCapacity()) {
  448. capacityComponent.activate();
  449. } else {
  450. capacityComponent.enable();
  451. }
  452. } else {
  453. capacityComponent.disable();
  454. }
  455. }
  456.  
  457. catch (e) {
  458. capacityComponent.disable();
  459. }
  460. }
  461.  
  462. Configurator.getProduct().selectCapacity(currentCapacity);
  463. Configurator.getProduct().resumeEventListeners();
  464. }
  465.  
  466. public async selectCapacity (capacity: string) {
  467. let capacityElement = this.getElement().querySelector(`[data-capacity="${capacity}"]`);
  468.  
  469. if (!capacityElement) {
  470. capacityElement = this.getElement().querySelectorAll('[data-capacity]')[0];
  471. capacity = capacityElement.dataset.capacity;
  472. }
  473.  
  474. if (capacityElement.className.indexOf('inactive') > -1) {
  475. return;
  476. }
  477.  
  478. for (const element of this.getElement().querySelectorAll('.capacity-choice')) {
  479. element.classList.remove('active');
  480. }
  481.  
  482. capacityElement.querySelector('.capacity-choice').className = 'capacity-choice active';
  483.  
  484. this
  485. .getElement()
  486. .querySelector('[data-capacityChoices] .item-title span')
  487. .innerHTML = capacity;
  488.  
  489. this.product.selectCapacity(capacity);
  490.  
  491. this.setPreview();
  492.  
  493. await this.updateColorComponents();
  494. }
  495.  
  496. public activateConfiguration () {
  497. const configurationElement = this.getElement().querySelector('.configuration');
  498.  
  499. configurationElement.className = 'configuration';
  500. }
  501.  
  502. public setTopFeatures (features: Array<string>) {
  503. const featuresElement = this.getElement().querySelector('.top-features ul');
  504. featuresElement.innerHTML = '';
  505.  
  506. for (const feature of features) {
  507. const element = document.createElement('li');
  508. element.innerHTML = feature;
  509.  
  510. featuresElement.appendChild(element);
  511. }
  512. }
  513.  
  514. public setPrice (price: number) {
  515. const priceElement = this.getElement().querySelector('.price');
  516.  
  517. priceElement.innerHTML = formatEuro(price);
  518. }
  519.  
  520. public setWhichTariff (label: string) {
  521. const whichTariffElement = this.getElement().querySelector('.pricing .description');
  522.  
  523. const descriptionLabel = 'Gerätepreis im Tarif ';
  524. const whichTariff = `<span class="which-tariff">${label} </span>`;
  525. const topSmartphoneDealUsed = `<span class="premium-smartphone">mit <b>Premium-Smartphone-Deal</b></span>`;
  526.  
  527. whichTariffElement.innerHTML = descriptionLabel + whichTariff;
  528.  
  529. if (this.product.usesTopSmartphoneDeal()) {
  530. whichTariffElement.innerHTML += topSmartphoneDealUsed;
  531. }
  532. }
  533.  
  534. public displayTopSmartphoneDeal () {
  535. const smartphoneDealTemplate = `
  536. <div class="fm-check option">
  537. <input type="checkbox" name="checkbox" id="checkbox" value="checkbox" ${this.product.usesTopSmartphoneDeal() ? 'checked' : ''}>
  538. <label for="checkbox" class="${this.product.usesTopSmartphoneDeal() ? 'checked' : ''}">
  539. <div class="bgdiv"></div>
  540. <span>Premium-Smartphone-Deal</span>
  541. </label>
  542. </div>
  543. <a href="#" class="tsd-overlay-trigger nsf-info-icon">
  544. <svg class="i-xsml">
  545. <use xlink:href="/simplicity/svgdefs.svg#i-tooltip-invert-lrg"></use>
  546. </svg>
  547. <svg class="i-xsml">
  548. <use xlink:href="/simplicity/svgdefs.svg#i-tooltip-lrg"></use>
  549. </svg>
  550. </a>
  551. `;
  552.  
  553. const element = document.createElement('div');
  554. element.className = 'premium-smartphone-deal';
  555. element.innerHTML = smartphoneDealTemplate;
  556.  
  557. this.topSmartphoneDealElement = element;
  558.  
  559. element.addEventListener('click', this.toggleTopSmartphoneDeal.bind(this));
  560.  
  561. this.getElement().querySelector('.pricing-box').appendChild(element);
  562.  
  563. this.getElement().querySelector('.tsd-overlay-trigger').addEventListener('click', (e) => {
  564. e.preventDefault();
  565. const triggerElement = this.getElement().querySelector('.premium-smartphone-deal-link');
  566. triggerElement.click();
  567.  
  568. this.updateTopSmartphoneDealOverlay();
  569. });
  570.  
  571. }
  572.  
  573. public async updateTopSmartphoneDealOverlay () {
  574. const overlay = document.getElementById('tariffDetails');
  575.  
  576. if ( overlay.offsetHeight === 0 ) {
  577. setTimeout(() => {
  578. this.updateTopSmartphoneDealOverlay();
  579. }, 100);
  580. }
  581.  
  582. const deviceimg = '<img src="https://www.vodafone.de/' + this.product.getImages().large + '">';
  583. const devicetitle = this.product.label;
  584.  
  585. let topSmartphoneDealActive = false;
  586.  
  587. if (this.product.usesTopSmartphoneDeal()) {
  588. topSmartphoneDealActive = true;
  589. }
  590.  
  591. Configurator.getProduct().stopEventListeners();
  592.  
  593. Configurator.getProduct().enableTopSmartphoneDeal();
  594. let reducedprice = await findOneByComponentSet([Configurator.getTariff(), Configurator.getProduct()]);
  595. reducedprice = formatEuro( reducedprice.getOnetimePrice() );
  596.  
  597. Configurator.getProduct().disableTopSmartphoneDeal();
  598. let price = await findOneByComponentSet([Configurator.getTariff(), Configurator.getProduct()]);
  599. price = formatEuro( price.getOnetimePrice() );
  600.  
  601. if (topSmartphoneDealActive) {
  602. Configurator.getProduct().enableTopSmartphoneDeal();
  603. } else {
  604. Configurator.getProduct().disableTopSmartphoneDeal();
  605. }
  606. Configurator.getProduct().resumeEventListeners();
  607.  
  608. jQuery(overlay).find('[data-sub20img]').html(deviceimg);
  609. jQuery(overlay).find('[data-devicetitle]').html(devicetitle);
  610. jQuery(overlay).find('[data-reducedprice]').html(reducedprice);
  611. jQuery(overlay).find('[data-price]').html(price);
  612.  
  613. }
  614.  
  615. public hideTopSmartphoneDeal () {
  616. if (this.topSmartphoneDealElement) {
  617. this.topSmartphoneDealElement.style.display = 'none';
  618. }
  619. }
  620.  
  621. public showTopSmartphoneDeal () {
  622. if (this.topSmartphoneDealElement) {
  623. this.topSmartphoneDealElement.style.display = 'inline-block';
  624. }
  625. }
  626.  
  627. public topSmartphoneDealChecked () {
  628. if (!this.topSmartphoneDealElement) {
  629. return false;
  630. }
  631.  
  632. const checkbox = this.topSmartphoneDealElement.querySelector('input');
  633.  
  634. return checkbox.checked;
  635. }
  636.  
  637. public checkTopSmartphoneDeal () {
  638. const checkbox = this.topSmartphoneDealElement.querySelector('input');
  639.  
  640. checkbox.checked = true;
  641. this.topSmartphoneDealElement.querySelector('label').classList.add('checked');
  642. }
  643.  
  644. public uncheckTopSmartphoneDeal () {
  645. const checkbox = this.topSmartphoneDealElement.querySelector('input');
  646.  
  647. if (checkbox.checked) {
  648. checkbox.checked = false;
  649. this.topSmartphoneDealElement.querySelector('label').classList.remove('checked');
  650. }
  651. }
  652.  
  653. public toggleTopSmartphoneDeal () {
  654. clearTimeout(this.checkboxTimeout);
  655.  
  656. this.checkboxTimeout = setTimeout(() => {
  657. const checkbox = this.topSmartphoneDealElement.querySelector('input');
  658.  
  659. if (checkbox.checked) {
  660. this.product.enableTopSmartphoneDeal();
  661. } else {
  662. this.product.disableTopSmartphoneDeal();
  663. }
  664. }, 10);
  665. }
  666.  
  667. public async showContainer () {
  668. const mainContainer = this.getElement().querySelector('.professional-article');
  669. const innerContainer = this.getElement().querySelector('.professional-article .inner-container');
  670.  
  671. mainContainer.className += ' loaded';
  672. innerContainer.className += ' loaded';
  673. }
  674.  
  675. public async show () {
  676. const mainHeadline = this.getElement().querySelector('.main-headline');
  677. const subHeadline = this.getElement().querySelector('.sub-headline');
  678. const loadingIndicator = this.getElement().querySelector('[data-loading-indicator]');
  679. const configurator = this.getElement().querySelector('.configurator');
  680.  
  681. if (mainHeadline) {
  682. mainHeadline.className += ' loaded';
  683. }
  684.  
  685. if (subHeadline) {
  686. setTimeout(() => {
  687. subHeadline.className += ' loaded';
  688. }, 50);
  689. }
  690.  
  691. setTimeout(() => {
  692. loadingIndicator.className += ' loaded';
  693. configurator.className += ' loaded';
  694. }, 100);
  695.  
  696. setTimeout(() => {
  697. loadingIndicator.parentNode.removeChild(loadingIndicator);
  698. }, 200);
  699. }
  700.  
  701. public showPromoBubble (imageUrl: string): void {
  702. let promoBubbleElement = this.getElement().querySelector('.promo-bubble');
  703.  
  704. if (!promoBubbleElement) {
  705. promoBubbleElement = document.createElement('div');
  706. promoBubbleElement.className = 'promo-bubble';
  707. this.getElement().querySelector('.top-features').appendChild(promoBubbleElement);
  708. }
  709.  
  710. promoBubbleElement.style.display = 'block';
  711.  
  712. promoBubbleElement.innerHTML = `<img src="${imageUrl}">`;
  713. }
  714.  
  715. public hidePromoBubble (): void {
  716. const promoBubbleElement = this.getElement().querySelector('.promo-bubble');
  717.  
  718. if (promoBubbleElement) {
  719. promoBubbleElement.style.display = 'none';
  720. }
  721. }
  722. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement