Current Path : /var/www/www-root/data/www/www.monolith-realty.ru/bitrix/js/landing/main/src/ |
Current File : /var/www/www-root/data/www/www.monolith-realty.ru/bitrix/js/landing/main/src/main.js |
import {Type, Dom, Cache, Tag, Text, Runtime} from 'main.core'; import {EventEmitter} from 'main.core.events'; import {Env} from 'landing.env'; import {Loc} from 'landing.loc'; import {Content} from 'landing.ui.panel.content'; import {SaveBlock} from 'landing.ui.panel.saveblock'; import {SliderHacks} from 'landing.sliderhacks'; import {PageObject} from 'landing.pageobject'; import hasBlock from './internal/has-block'; import hasCreateButton from './internal/has-create-button'; import onAnimationEnd from './internal/on-animation-end'; import isEmpty from './internal/is-empty'; import {ExternalControls} from './external.controls'; import {Backend} from 'landing.backend'; BX.Landing.getMode = () => 'edit'; /** * @memberOf BX.Landing */ export class Main extends EventEmitter { static TYPE_PAGE = 'PAGE'; static TYPE_STORE = 'STORE'; static TYPE_KNOWLEDGE = 'KNOWLEDGE'; static TYPE_GROUP = 'GROUP'; static getMode() { return 'edit'; } static createInstance(id: number) { const rootWindow = BX.Landing.PageObject.getRootWindow(); rootWindow.BX.Landing.Main.instance = new BX.Landing.Main(id); } static getInstance(): Main { const rootWindow = BX.Landing.PageObject.getRootWindow(); rootWindow.BX.Reflection.namespace('BX.Landing.Main'); if (rootWindow.BX.Landing.Main.instance) { return rootWindow.BX.Landing.Main.instance; } rootWindow.BX.Landing.Main.instance = new Main(-1); return rootWindow.BX.Landing.Main.instance; } /** * Returns true, if current page is Editor. * @return {boolean} */ static isEditorMode() { return Dom.hasClass(document.body, 'landing-editor'); } /** * Returns true, if external controls is enabled. * @return {boolean} */ static isExternalControlsEnabled() { return Dom.hasClass(document.body, 'enable-external-controls'); } /** * Returns in percent scroll position of page. * * @return {number} */ static topInPercent(): number { const scrollHeight = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; return scrollTop / scrollHeight * 100; } /** * Landing ID * @type {number} */ id: number; constructor(id: number) { super(); this.setEventNamespace('BX.Landing.Main'); const options = Env.getInstance().getOptions(); this.id = id; this.options = Object.freeze(options); this.blocks = this.options.blocks; this.currentBlock = null; this.isDesignBlockModeFlag = this.options["design_block"] === true; this.loadedDeps = {}; this.cache = new Cache.MemoryCache(); this.externalControls = new ExternalControls; this.onSliderFormLoaded = this.onSliderFormLoaded.bind(this); this.onBlockDelete = this.onBlockDelete.bind(this); BX.addCustomEvent('Landing.Block:onAfterDelete', this.onBlockDelete); this.adjustEmptyAreas(); BX.Landing.UI.Panel.StatusPanel.setLastModified(options.lastModified); if (!this.isDesignBlockModeFlag) { BX.Landing.UI.Panel.StatusPanel.getInstance().show(); } const pageType = Env.getInstance().getType(); if ( pageType === Main.TYPE_KNOWLEDGE || pageType === Main.TYPE_GROUP ) { const mainArea = document.querySelector('.landing-main'); if (Type.isDomNode(mainArea)) { Dom.addClass(mainArea, 'landing-ui-collapse'); } } } isCrmFormPage(): boolean { return Env.getInstance().getOptions().specialType === 'crm_forms'; } isDesignBlockMode() { return this.isDesignBlockModeFlag; } getSaveBlockPanel(): Content { const panel = new SaveBlock('save_block_panel', {block: this.currentBlock}); panel.layout.hidden = true; panel.content.hidden = false; Dom.append(panel.layout, window.parent.document.body); return panel; } getBlocksPanel(): Content { return this.cache.remember('blockPanel', () => { const blocksPanel = this.createBlocksPanel(); setTimeout(() => { if (blocksPanel.sidebarButtons.get(this.options.default_section)) { blocksPanel.sidebarButtons.get(this.options.default_section).layout.click(); } else { [...blocksPanel.sidebarButtons][0].layout.click(); } }); blocksPanel.layout.hidden = true; blocksPanel.content.hidden = false; Dom.append(blocksPanel.layout, window.parent.document.body); return blocksPanel; }); } hideBlocksPanel() { if (this.getBlocksPanel()) { return this.getBlocksPanel().hide(); } return Promise.resolve(); } getLayoutAreas(): Array<HTMLElement> { return this.cache.remember('layoutAreas', () => { return [ ...document.body.querySelectorAll('.landing-header'), ...document.body.querySelectorAll('.landing-sidebar'), ...document.body.querySelectorAll('.landing-main'), ...document.body.querySelectorAll('.landing-footer'), ]; }); } /** * Creates insert block button * @param {HTMLElement} area * @return {BX.Landing.UI.Button.Plus} */ createInsertBlockButton(area: HTMLElement) { const button = new BX.Landing.UI.Button.Plus('insert_first_block', { text: Loc.getMessage('ACTION_BUTTON_CREATE'), }); button.on('click', this.showBlocksPanel.bind(this, null, area, button)); button.on('mouseover', this.onCreateButtonMouseover.bind(this, area, button)); button.on('mouseout', this.onCreateButtonMouseout.bind(this, area, button)); return button; } onCreateButtonMouseover(area: HTMLElement, button) { if ( Dom.hasClass(area, 'landing-header') || Dom.hasClass(area, 'landing-footer') ) { const areas = this.getLayoutAreas(); if (areas.length > 1) { const createText = Loc.getMessage('ACTION_BUTTON_CREATE'); if (Dom.hasClass(area, 'landing-main')) { button.setText( `${createText} ${Loc.getMessage('LANDING_ADD_BLOCK_TO_MAIN')}`, ); } if (Dom.hasClass(area, 'landing-header')) { button.setText( `${createText} ${Loc.getMessage('LANDING_ADD_BLOCK_TO_HEADER')}`, ); } if (Dom.hasClass(area, 'landing-sidebar')) { button.setText( `${createText} ${Loc.getMessage('LANDING_ADD_BLOCK_TO_SIDEBAR')}`, ); } if (Dom.hasClass(area, 'landing-footer')) { button.setText( `${createText} ${Loc.getMessage('LANDING_ADD_BLOCK_TO_FOOTER')}`, ); } clearTimeout(this.fadeTimeout); this.fadeTimeout = setTimeout(() => { Dom.addClass(area, 'landing-area-highlight'); areas .filter((currentArea) => currentArea !== area) .forEach((currentArea) => { Dom.addClass(currentArea, 'landing-area-fade'); }); }, 400); } } } onCreateButtonMouseout(area, button) { clearTimeout(this.fadeTimeout); if (Dom.hasClass(area, 'landing-header') || Dom.hasClass(area, 'landing-footer')) { const areas = this.getLayoutAreas(); if (areas.length > 1) { button.setText(Loc.getMessage('ACTION_BUTTON_CREATE')); areas.forEach((currentArea) => { Dom.removeClass(currentArea, 'landing-area-highlight'); Dom.removeClass(currentArea, 'landing-area-fade'); }); } } } initEmptyArea(area: HTMLElement) { if (area) { area.innerHTML = ''; Dom.append(this.createInsertBlockButton(area).layout, area); Dom.addClass(area, 'landing-empty'); } } // eslint-disable-next-line class-methods-use-this destroyEmptyArea(area: HTMLElement) { if (area) { const button = area.querySelector('button[data-id="insert_first_block"]'); if (button) { Dom.remove(button); } Dom.removeClass(area, 'landing-empty'); } } /** * Adjusts areas */ adjustEmptyAreas() { this.getLayoutAreas() .filter((area) => { return hasBlock(area) && hasCreateButton(area); }) .forEach(this.destroyEmptyArea, this); this.getLayoutAreas() .filter((area) => { return !hasBlock(area) && !hasCreateButton(area); }) .forEach(this.initEmptyArea, this); const main = document.body.querySelector('main.landing-edit-mode'); const isAllEmpty = !this.getLayoutAreas().some(hasBlock); if (main) { if (isAllEmpty) { Dom.addClass(main, 'landing-empty'); return; } Dom.removeClass(main, 'landing-empty'); } } /** * Enables landing controls */ // eslint-disable-next-line class-methods-use-this enableControls() { Dom.removeClass(document.body, 'landing-ui-hide-controls'); } /** * Disables landing controls */ // eslint-disable-next-line class-methods-use-this disableControls() { Dom.addClass(document.body, 'landing-ui-hide-controls'); } /** * Checks that landing controls is enabled * @return {boolean} */ // eslint-disable-next-line class-methods-use-this isControlsEnabled() { return !Dom.hasClass(document.body, 'landing-ui-hide-controls'); } /** * Makes landing controls internal. */ // eslint-disable-next-line class-methods-use-this makeControlsInternal() { BX.onCustomEvent('BX.Landing.Main:changeControls', ['internal', Main.topInPercent()]); Dom.removeClass(document.body, 'landing-ui-external-controls'); } /** * Makes landing controls external. */ // eslint-disable-next-line class-methods-use-this makeControlsExternal() { BX.onCustomEvent('BX.Landing.Main:changeControls', ['external', Main.topInPercent()]); Dom.addClass(document.body, 'landing-ui-external-controls'); } /** * Checks that landing controls is external. * @return {boolean} */ // eslint-disable-next-line class-methods-use-this isControlsExternal() { return Dom.hasClass(document.body, 'landing-ui-external-controls'); } /** * Set device code in body data-attribute. * @param {string} code */ setDeviceCode(code: string) { document.body.setAttribute('data-device', code); } /** * Get device code from body attribute. * @return {string} */ getDeviceCode(): ?string { return document.body.getAttribute('data-device'); } /** * Set BX classes to mark this landing frame as mobile (touch) device */ setTouchDevice() { Dom.removeClass(document.documentElement, 'bx-no-touch'); Dom.addClass(document.documentElement, 'bx-touch'); } /** * Set BX classes to mark this landing frame as desktop (no touch) device */ setNoTouchDevice() { Dom.removeClass(document.documentElement, 'bx-touch'); Dom.addClass(document.documentElement, 'bx-no-touch'); } /** * Appends block * @param {addBlockResponse} data * @param {boolean} [withoutAnimation] * @returns {HTMLElement} */ appendBlock(data, withoutAnimation) { const block = Tag.render`${data.content}`; block.id = `block${data.id}`; if (!withoutAnimation) { Dom.addClass(block, 'landing-ui-show'); onAnimationEnd(block, 'showBlock').then(() => { Dom.removeClass(block, 'landing-ui-show'); }); } this.insertToBlocksFlow(block); return block; } /** * Shows blocks list panel * @param {BX.Landing.Block} block * @param {HTMLElement} [area] * @param [button] * @param [insertBefore] */ showBlocksPanel(block, area, button, insertBefore) { this.currentBlock = block; this.currentArea = area; this.insertBefore = insertBefore; BX.Landing.UI.Panel.EditorPanel.getInstance().hide(); if (this.isCrmFormPage() || this.isControlsExternal()) { const rootWindow = PageObject.getRootWindow(); Dom.append(this.getBlocksPanel().layout, rootWindow.document.body); Dom.append(this.getBlocksPanel().overlay, rootWindow.document.body); } this.getBlocksPanel().show(); this.disableAddBlockButtons(); if (!!area && !!button) { this.onCreateButtonMouseout(area, button); } } showSaveBlock(block) { this.currentBlock = block; this.getSaveBlockPanel().show(); } disableAddBlockButtons() { PageObject.getBlocks().forEach((block) => { const panel = block.panels.get('create_action'); if (panel) { const button = panel.buttons.get('insert_after'); if (button) { button.disable(); } } }); } enableAddBlockButtons() { PageObject.getBlocks().forEach((block) => { const panel = block.panels.get('create_action'); if (panel) { const button = panel.buttons.get('insert_after'); if (button) { button.enable(); } } }); } /** * Creates blocks list panel * @returns {BX.Landing.UI.Panel.Content} */ createBlocksPanel() { const {blocks} = this.options; const categories = Object.keys(blocks); const panel = new Content('blocks_panel', { title: Loc.getMessage('LANDING_CONTENT_BLOCKS_TITLE'), className: 'landing-ui-panel-block-list', scrollAnimation: true, }); panel.subscribe('onCancel', () => { this.enableAddBlockButtons(); }); categories.forEach((categoryId) => { const hasItems = !isEmpty(blocks[categoryId].items); const isPopular = categoryId === 'popular'; const isSeparator = blocks[categoryId].separator; if ((hasItems && !isPopular) || isSeparator) { panel.appendSidebarButton( this.createBlockPanelSidebarButton(categoryId, blocks[categoryId]), ); } }); panel.appendSidebarButton( new BX.Landing.UI.Button.SidebarButton('feedback_button', { className: 'landing-ui-button-sidebar-feedback', text: Loc.getMessage('LANDING_BLOCKS_LIST_FEEDBACK_BUTTON'), onClick: this.showFeedbackForm.bind(this), }), ); return panel; } /** * Shows feedback form * @param data */ showSliderFeedbackForm(data = {}) { Runtime.loadExtension('ui.feedback.form').then(() => { const data = {}; data.bitrix24 = this.options.server_name; data.siteId = this.options.site_id; data.siteUrl = this.options.url; data.siteTemplate = this.options.xml_id; data.productType = this.options.productType || 'Undefined'; data.typeproduct = (() => { if (this.options.params.type === Main.TYPE_GROUP) { return 'KNOWLEDGE_GROUP'; } return this.options.params.type; })(); BX.UI.Feedback.Form.open( { id: Math.random()+'', forms: this.getFeedbackFormOptions(), presets: data, } ); }); } /** * Gets feedback form options * @return {{id: string, sec: string, lang: string}} */ // eslint-disable-next-line class-methods-use-this getFeedbackFormOptions() { return [ {zones: ['en', 'eu', 'in', 'uk'], id: 16, lang: 'en', sec: '3h483y'}, {zones: ['ru', 'by', 'kz'], id: 8, lang: 'ru', sec: 'x80yjw'}, {zones: ['ua'], id: 18, lang: 'ua', sec: 'd9e09o'}, {zones: ['la', 'co', 'mx'], id: 14, lang: 'la', sec: 'wu561i'}, {zones: ['de'], id: 10, lang: 'de', sec: 'eraz2q'}, {zones: ['com.br', 'br'], id: 12, lang: 'br', sec: 'r6wvge'}, ]; } /** * Handles feedback loaded event */ onSliderFormLoaded() { this.sliderFormLoader.hide(); } /** * Shows feedback form for blocks list panel */ showFeedbackForm() { this.showSliderFeedbackForm({target: 'blocksList'}); } /** * Initialises feedback form */ // eslint-disable-next-line class-methods-use-this initFeedbackForm() { const rootWindow = PageObject.getRootWindow(); ((w, d, u, b) => { w.Bitrix24FormObject = b; w[b] = w[b] || function() { // eslint-disable-next-line prefer-rest-params arguments[0].ref = u; // eslint-disable-next-line prefer-rest-params (w[b].forms = w[b].forms || []).push(arguments[0]); }; if (w[b].forms) return; const s = d.createElement('script'); const r = 1 * new Date(); s.async = 1; s.src = `${u}?${r}`; const h = d.getElementsByTagName('script')[0]; h.parentNode.insertBefore(s, h); })(rootWindow, rootWindow.document, 'https://product-feedback.bitrix24.com/bitrix/js/crm/form_loader.js', 'b24formFeedBack'); } /** * Creates blocks list panel sidebar button * @param {string} category * @param {object} options * @returns {BX.Landing.UI.Button.SidebarButton} */ createBlockPanelSidebarButton(category, options) { return new BX.Landing.UI.Button.SidebarButton(category, { text: options.name, child: !options.separator, className: options.new ? 'landing-ui-new-section' : '', onClick: this.onBlocksListCategoryChange.bind(this, category), }); } /** * Adds dynamically new block to the category. * @param {string} category Category code. * @param {{code: string, name: string, preview: string, section: Array<string>}} block Block data. */ addNewBlockToCategory(category, block) { if (this.blocks[category]) { const blockCode = block['codeOriginal'] || block['code']; if (category === 'last') { if (!this.lastBlocks) { this.lastBlocks = Object.keys(this.blocks.last.items); } this.lastBlocks.unshift(blockCode); } else { this.blocks[category].items[blockCode] = block; } this.onBlocksListCategoryChange(category); } } removeBlockFromList(blockCode: string) { let removed = false; for (let category in this.blocks) { if (this.blocks[category].items[blockCode] !== undefined) { delete this.blocks[category].items[blockCode]; removed = true; } } if (this.lastBlocks.indexOf(blockCode) !== -1) { this.lastBlocks.splice(this.lastBlocks.indexOf(blockCode), 1); removed = true; } // refresh panel if (removed) { const activeCategoryButton = this.getBlocksPanel().sidebarButtons.find((button) => { return Dom.hasClass(button.layout, 'landing-ui-active'); }); if (activeCategoryButton) { this.onBlocksListCategoryChange(activeCategoryButton.id); } } } /** * Returns page's template code if exists. * @return {string|null} */ getTemplateCode() { let { tplCode } = Env.getInstance().getOptions(); if (tplCode.indexOf('@') > 0) { tplCode = tplCode.split('@')[1]; } if (!tplCode || tplCode.length <= 0) { tplCode = null; } return tplCode; } /** * Handles event on blocks list category change * @param {string} category - Category id */ onBlocksListCategoryChange(category) { const templateCode = this.getTemplateCode(); this.getBlocksPanel().content.hidden = false; this.getBlocksPanel().sidebarButtons.forEach((button) => { const action = button.id === category ? 'add' : 'remove'; button.layout.classList[action]('landing-ui-active'); }); this.getBlocksPanel().content.innerHTML = ''; if (category === 'last') { if (!this.lastBlocks) { this.lastBlocks = Object.keys(this.blocks.last.items); } this.lastBlocks = [...new Set(this.lastBlocks)]; this.lastBlocks.forEach((blockKey) => { const block = this.getBlockFromRepository(blockKey); this.getBlocksPanel().appendCard(this.createBlockCard(blockKey, block)); }); return; } Object.keys(this.blocks[category].items).forEach((blockKey) => { const block = this.blocks[category].items[blockKey]; const blockTplCode = (block['tpl_code'] && block['tpl_code'].length > 0) ? block['tpl_code'] : null; if ( !templateCode || !blockTplCode || (blockTplCode && blockTplCode === templateCode) ) { this.getBlocksPanel().appendCard(this.createBlockCard(blockKey, block)); } }); if (this.getBlocksPanel().content.scrollTop) { requestAnimationFrame(() => { this.getBlocksPanel().content.scrollTop = 0; }); } } // eslint-disable-next-line consistent-return getBlockFromRepository(code) { const {blocks} = this.options; const categories = Object.keys(blocks); const category = categories.find((categoryId) => { return code in blocks[categoryId].items; }); if (category) { return blocks[category].items[code]; } } /** * Handles copy block event * @param {BX.Landing.Block} block */ // eslint-disable-next-line class-methods-use-this onCopyBlock(block) { window.localStorage.landingBlockId = block.id; window.localStorage.landingBlockName = block.manifest.block.name; window.localStorage.landingBlockAction = 'copy'; try { window.localStorage.requiredUserAction = JSON.stringify( block.requiredUserActionOptions, ); } catch (err) { window.localStorage.requiredUserAction = ''; } } /** * Handles cut block event * @param {BX.Landing.Block} block */ // eslint-disable-next-line class-methods-use-this onCutBlock(block) { window.localStorage.landingBlockId = block.id; window.localStorage.landingBlockName = block.manifest.block.name; window.localStorage.landingBlockAction = 'cut'; try { window.localStorage.requiredUserAction = JSON.stringify( block.requiredUserActionOptions, ); } catch (err) { window.localStorage.requiredUserAction = ''; } BX.Landing.PageObject.getBlocks().remove(block); Dom.remove(block.node); BX.onCustomEvent('Landing.Block:onAfterDelete', [block]); } /** * Handles paste block event * @param {BX.Landing.Block} block * @param {() => {}} callback */ onPasteBlock(block, callback) { if (window.localStorage.landingBlockId) { let action = 'Landing::copyBlock'; if (window.localStorage.landingBlockAction === 'cut') { action = 'Landing::moveBlock'; } const requestBody = {}; requestBody[action] = { action, data: { lid: block.lid || BX.Landing.Main.getInstance().id, block: window.localStorage.landingBlockId, params: { AFTER_ID: block.id, RETURN_CONTENT: 'Y', }, }, }; BX.Landing.Backend.getInstance() .batch(action, requestBody, {action}) .then((res) => { this.currentBlock = block; return this.addBlock(res[action].result.content, false, false, callback); }); } } /** * Adds block from server response * @param {addBlockResponse} res * @param {boolean} [withoutAnimation = false] * @param {boolean} [insertBefore = false] * @param {() => {}} callback * @return {Promise<T>} */ addBlock(res, withoutAnimation, insertBefore = false, callback) { if (this.lastBlocks) { this.lastBlocks.unshift(res.manifest.codeOriginal || res.manifest.code); } const self = this; const block = this.appendBlock(res, withoutAnimation); return this.loadBlockDeps(res) .then((blockRes) => { self.currentBlock = null; self.currentArea = null; const blockId = parseInt(res.id); const allOldBlocks = BX.Landing.PageObject.getBlocks(); if (allOldBlocks) { allOldBlocks.forEach((oldBlock) => { if (oldBlock.id === blockId) { Dom.remove(oldBlock.node); BX.Landing.PageObject.getBlocks().remove(oldBlock); } }); } // Init block entity void new BX.Landing.Block(block, { id: blockId, sections: res.sections, requiredUserAction: res.requiredUserAction, manifest: res.manifest, access: res.access, active: Text.toBoolean(res.active), php: res.php, designed: res.designed, anchor: res.anchor, dynamicParams: res.dynamicParams, repoId: res.repoId, }); return self.runBlockScripts(res) .then(() => { if (callback) { callback(blockId); } return block; }); }) .catch((err) => { console.warn(err); }); } /** * Handles edd block event * @param {string} blockCode * @param {*} [restoreId] * @param {?boolean} [preventHistory = false] * @return {Promise<BX.Landing.Block>} */ onAddBlock(blockCode, restoreId, preventHistory: ?boolean = false) { const id = Text.toNumber(restoreId); this.hideBlocksPanel(); return this.showBlockLoader() .then(this.loadBlock(blockCode, id, preventHistory)) .then((res) => { return new Promise((resolve) => { setTimeout(() => { resolve(res); }, 500); }); }) .then((res) => { res.manifest.codeOriginal = blockCode; const p = this.addBlock(res, false, this.insertBefore); this.insertBefore = false; this.adjustEmptyAreas(); void this.hideBlockLoader(); this.enableAddBlockButtons(); BX.onCustomEvent('BX.Landing.Block:onAfterAdd', res); return p; }); } /** * Inserts element to blocks flow. * Element can be inserted after current block or after last block * @param {HTMLElement} element */ insertToBlocksFlow(element) { const isCurrentBlockAvailable = ( this.currentBlock && this.currentBlock.node && this.currentBlock.node.parentNode ); if (isCurrentBlockAvailable && !this.insertBefore) { Dom.insertAfter(element, this.currentBlock.node); return; } if (isCurrentBlockAvailable && this.insertBefore) { Dom.insertBefore(element, this.currentBlock.node); } Dom.prepend(element, this.currentArea); } /** * Gets block loader * @return {HTMLElement} */ getBlockLoader() { if (!this.blockLoader) { this.blockLoader = new BX.Loader({size: 60}); this.blockLoaderContainer = Dom.create('div', { props: {className: 'landing-block-loader-container'}, children: [this.blockLoader.layout], }); } return this.blockLoaderContainer; } /** * Shows block loader * @return {Function} */ showBlockLoader() { this.insertToBlocksFlow(this.getBlockLoader()); this.blockLoader.show(); return Promise.resolve(); } /** * Hides block loader * @return {Function} */ hideBlockLoader() { Dom.remove(this.getBlockLoader()); this.blockLoader = null; return Promise.resolve(); } /** * Loads block dependencies * @param {addBlockResponse} data * @returns {Promise<addBlockResponse>} */ loadBlockDeps(data) { const ext = BX.processHTML(data.content_ext); if (BX.type.isArray(ext.SCRIPT)) { ext.SCRIPT = ext.SCRIPT.filter((item) => { return !item.isInternal; }); } let loadedScripts = 0; const scriptsCount = (data.js.length + ext.SCRIPT.length + ext.STYLE.length + data.css.length); let resPromise = null; if (!this.loadedDeps[data.manifest.code] && scriptsCount > 0) { resPromise = new Promise(((resolve) => { function onLoad() { loadedScripts += 1; if (loadedScripts === scriptsCount) { resolve(data); } } if (scriptsCount > loadedScripts) { // Load extensions files ext.SCRIPT.forEach((item) => { if (!item.isInternal) { BX.loadScript(item.JS, onLoad); } }); ext.STYLE.forEach((item) => { BX.loadScript(item, onLoad); }); // Load block files data.css.forEach((item) => { BX.loadScript(item, onLoad); }); data.js.forEach((item) => { BX.loadScript(item, onLoad); }); } else { onLoad(); } this.loadedDeps[data.manifest.code] = true; })); } else { resPromise = Promise.resolve(data); } return resPromise; } /** * Executes block scripts * @param data * @return {Promise} */ // eslint-disable-next-line class-methods-use-this runBlockScripts(data) { return new Promise(((resolve) => { const scripts = BX.processHTML(data.content).SCRIPT; if (scripts.length) { BX.ajax.processScripts(scripts, undefined, () => { resolve(data); }); } else { resolve(data); } })); } /** * Load new block from server * @param {string} blockCode * @param {int} [restoreId] * @param {boolean} [preventHistory = false] * @returns {Function} */ loadBlock(blockCode, restoreId, preventHistory) { return () => { let lid = this.id; let siteId = this.options.site_id; if (this.currentBlock) { lid = this.currentBlock.lid; siteId = this.currentBlock.siteId; } if (this.currentArea) { lid = Dom.attr(this.currentArea, 'data-landing'); siteId = Dom.attr(this.currentArea, 'data-site'); } let requestBody = { lid, siteId, preventHistory: preventHistory ? 1 : 0, }; const fields = { ACTIVE: 'Y', CODE: blockCode, AFTER_ID: this.currentBlock ? this.currentBlock.id : 0, RETURN_CONTENT: 'Y', }; if (!Type.isBoolean(preventHistory) || preventHistory === false) { // Change history steps BX.Landing.History.getInstance().push(); } if (!restoreId) { requestBody.fields = fields; return Backend .getInstance() .action('Landing::addBlock', requestBody, {code: blockCode}) .then(result => { if (this.insertBefore) { return Backend .getInstance() .action('Landing::upBlock', { lid, siteId, block: result.id, }) .then(() => { return result; }); } return result; }); } return BX.Landing.Backend.getInstance() .action('Block::getContent', { block: restoreId, lid, fields, editMode: 1, }) .then((res) => { res.id = restoreId; return res; }); }; } /** * Creates block preview card * @param {string} blockKey - Block key (folder name) * @param {{name: string, [preview]: ?string, [new]: ?boolean}} block - Object with block data * @param {string} [mode] * @returns {BX.Landing.UI.Card.BlockPreviewCard} */ createBlockCard(blockKey, block, mode) { return new BX.Landing.UI.Card.BlockPreviewCard({ title: block.name, image: block.preview, code: blockKey, app_expired: block.app_expired, favorite: !!block.favorite, favoriteMy: !!block.favoriteMy, repo_id: block.repo_id, mode, isNew: block.new === true, onClick: this.onAddBlock.bind(this, blockKey), }); } /** * Handles block delete event */ onBlockDelete(block) { if (!block.parent.querySelector('.block-wrapper')) { this.adjustEmptyAreas(); } } /** * Shows page overlay */ // eslint-disable-next-line class-methods-use-this showOverlay() { const main = document.querySelector('main.landing-edit-mode'); if (main) { Dom.addClass(main, 'landing-ui-overlay'); } } /** * Hides page overlay */ // eslint-disable-next-line class-methods-use-this hideOverlay() { const main = document.querySelector('main.landing-edit-mode'); if (main) { Dom.removeClass(main, 'landing-ui-overlay'); } } reloadSlider(url: string): Promise<any> { return SliderHacks.reloadSlider(url, window.parent); } }