Update
This commit is contained in:
308
core/bitrix/js/landing/ui/field/aha_guides.js
Normal file
308
core/bitrix/js/landing/ui/field/aha_guides.js
Normal file
@@ -0,0 +1,308 @@
|
||||
;(function() {
|
||||
'use strict';
|
||||
|
||||
BX.namespace('BX.Landing.UI.Guide');
|
||||
|
||||
/**
|
||||
* @typedef {Object} TourManagerConfig
|
||||
* @property {number} id
|
||||
* @property {string} selector
|
||||
* @property {?string} requiredChildSelector
|
||||
* @property {Function} checkCondition
|
||||
* @property {Function} showGuide
|
||||
* @property {Function} markAsShown
|
||||
*/
|
||||
|
||||
BX.Landing.UI.Guide.TourManager = class TourManager
|
||||
{
|
||||
registeredGuides = new Map();
|
||||
observer = null;
|
||||
|
||||
/**
|
||||
* @param {TourManagerConfig} config
|
||||
* @return {void}
|
||||
*/
|
||||
register(config)
|
||||
{
|
||||
this.registeredGuides.set(config.id, config);
|
||||
|
||||
if (!this.observer)
|
||||
{
|
||||
this.startObserving();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {void}
|
||||
*/
|
||||
startObserving()
|
||||
{
|
||||
if (this.observer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.observer = new MutationObserver(this.#handleMutations.bind(this));
|
||||
|
||||
this.observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {MutationRecord[]} mutations
|
||||
*/
|
||||
#handleMutations(mutations)
|
||||
{
|
||||
for (const mutation of mutations)
|
||||
{
|
||||
if (mutation.type === 'childList')
|
||||
{
|
||||
mutation.addedNodes.forEach(this.#processAddedNode.bind(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Node} node
|
||||
*/
|
||||
#processAddedNode(node)
|
||||
{
|
||||
if (node.nodeType === Node.ELEMENT_NODE)
|
||||
{
|
||||
this.checkNodeForTargets(node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {void}
|
||||
*/
|
||||
stopObserving()
|
||||
{
|
||||
if (this.observer)
|
||||
{
|
||||
this.observer.disconnect();
|
||||
this.observer = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Element} node
|
||||
* @return {void}
|
||||
*/
|
||||
checkNodeForTargets(node)
|
||||
{
|
||||
for (const [guideId, config] of this.registeredGuides)
|
||||
{
|
||||
try
|
||||
{
|
||||
const targetElement = node.matches(config.selector)
|
||||
? node
|
||||
: node.querySelector(config.selector)
|
||||
;
|
||||
|
||||
if (!targetElement)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (config.requiredChildSelector)
|
||||
{
|
||||
const requiredChild = targetElement.querySelector(config.requiredChildSelector);
|
||||
if (!requiredChild)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
this.processGuide(guideId, config, targetElement);
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} guideId
|
||||
* @param {TourManagerConfig} config
|
||||
* @param {Element} targetElement
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
async processGuide(guideId, config, targetElement)
|
||||
{
|
||||
this.registeredGuides.delete(guideId);
|
||||
|
||||
try
|
||||
{
|
||||
const shouldShow = await config.checkCondition();
|
||||
if (!shouldShow)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await config.showGuide(targetElement);
|
||||
|
||||
if (config.markAsShown)
|
||||
{
|
||||
config.markAsShown();
|
||||
}
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (this.registeredGuides.size === 0)
|
||||
{
|
||||
this.stopObserving();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const tourManager = new BX.Landing.UI.Guide.TourManager();
|
||||
|
||||
BX.ready(() => {
|
||||
if (!BX.UI?.Tour?.Guide || !BX.Event)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const Guide = BX.UI.Tour.Guide;
|
||||
const Event = BX.Event;
|
||||
|
||||
/**
|
||||
* @return {Promise<boolean>}
|
||||
*/
|
||||
function wasPhoneGuideShown()
|
||||
{
|
||||
return new Promise((resolve) => {
|
||||
BX.ajax.runAction('landing.landing.isPhoneRegionCodeTourAlreadySeen')
|
||||
.then(
|
||||
(response) => {
|
||||
resolve(response.data);
|
||||
},
|
||||
() => {
|
||||
resolve(false);
|
||||
},
|
||||
)
|
||||
.catch(() => {
|
||||
resolve(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {void}
|
||||
*/
|
||||
function markPhoneGuideAsShown()
|
||||
{
|
||||
BX.userOptions.save('ui-tour', 'landing_phone_aha_shown', 'null', 'Y');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Element} targetElement
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function showPhoneGuide(targetElement)
|
||||
{
|
||||
return new Promise((resolve) => {
|
||||
try
|
||||
{
|
||||
const pencilIcon = targetElement.querySelector('.landing-ui-button-icon-edit');
|
||||
|
||||
const guide = new Guide({
|
||||
id: 'landing-phone-field-aha-moment',
|
||||
overlay: true,
|
||||
simpleMode: true,
|
||||
onEvents: false,
|
||||
steps: [
|
||||
{
|
||||
target: targetElement,
|
||||
title: '',
|
||||
text: BX.Landing.Loc.getMessage('LANDING_PHONE_FIELD_AHA_MOMENT_REGION_CODE'),
|
||||
position: 'bottom',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
guide.getPopup().setWidth(350);
|
||||
|
||||
const adjustPositionAndAngle = () => {
|
||||
const popup = guide.getPopup();
|
||||
if (!popup || !popup.getPopupContainer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const popupContainer = popup.getPopupContainer();
|
||||
const targetRect = targetElement.getBoundingClientRect();
|
||||
|
||||
const newLeft = targetRect.right - popupContainer.offsetWidth;
|
||||
BX.Dom.style(popupContainer, { left: `${newLeft}px` });
|
||||
|
||||
const angleElement = popup.angle?.element;
|
||||
|
||||
if (angleElement && pencilIcon)
|
||||
{
|
||||
const pencilRect = pencilIcon.getBoundingClientRect();
|
||||
const pencilCenterX = pencilRect.left + (pencilRect.width / 2);
|
||||
const angleLeftOffset = pencilCenterX - newLeft;
|
||||
const angleWidth = angleElement.offsetWidth;
|
||||
BX.Dom.style(angleElement, { left: `${angleLeftOffset - (angleWidth / 2)}px` });
|
||||
}
|
||||
};
|
||||
|
||||
const onClose = () => {
|
||||
Event.unbind(window, 'resize', adjustPositionAndAngle);
|
||||
Event.unbind(document, 'scroll', adjustPositionAndAngle, true);
|
||||
resolve();
|
||||
};
|
||||
|
||||
guide.getPopup().subscribe('onClose', onClose);
|
||||
guide.getPopup().subscribe('onDestroy', onClose);
|
||||
|
||||
guide.start();
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
const popupContainer = guide.getPopup().getPopupContainer();
|
||||
if (popupContainer)
|
||||
{
|
||||
BX.Dom.style(popupContainer, { zIndex: '1050' });
|
||||
}
|
||||
});
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
adjustPositionAndAngle();
|
||||
});
|
||||
|
||||
Event.bind(window, 'resize', adjustPositionAndAngle);
|
||||
Event.bind(document, 'scroll', adjustPositionAndAngle, true);
|
||||
|
||||
resolve();
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
tourManager.register({
|
||||
id: 'landing-phone-field-aha',
|
||||
selector: '.landing-ui-component-list-item[data-type="phone"]',
|
||||
requiredChildSelector: '.landing-ui-button-icon-edit',
|
||||
checkCondition: async () => {
|
||||
const isShown = await wasPhoneGuideShown();
|
||||
|
||||
return !isShown;
|
||||
},
|
||||
showGuide: showPhoneGuide,
|
||||
markAsShown: markPhoneGuideAsShown,
|
||||
});
|
||||
});
|
||||
})();
|
||||
1
core/bitrix/js/landing/ui/field/aha_guides.map.js
Normal file
1
core/bitrix/js/landing/ui/field/aha_guides.map.js
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"aha_guides.map.js","names":["BX","namespace","Landing","UI","Guide","TourManager","registeredGuides","Map","observer","register","config","this","set","id","startObserving","MutationObserver","handleMutations","bind","observe","document","body","childList","subtree","mutations","mutation","type","addedNodes","forEach","processAddedNode","node","nodeType","Node","ELEMENT_NODE","checkNodeForTargets","stopObserving","disconnect","guideId","targetElement","matches","selector","querySelector","requiredChildSelector","requiredChild","processGuide","error","delete","shouldShow","checkCondition","showGuide","markAsShown","size","tourManager","ready","Tour","Event","wasPhoneGuideShown","Promise","resolve","ajax","runAction","then","response","data","catch","markPhoneGuideAsShown","userOptions","save","showPhoneGuide","pencilIcon","guide","overlay","simpleMode","onEvents","steps","target","title","text","Loc","getMessage","position","getPopup","setWidth","adjustPositionAndAngle","popup","getPopupContainer","popupContainer","targetRect","getBoundingClientRect","newLeft","right","offsetWidth","Dom","style","left","angleElement","angle","element","pencilRect","pencilCenterX","width","angleLeftOffset","angleWidth","onClose","unbind","window","subscribe","start","requestAnimationFrame","zIndex","async","isShown"],"sources":["aha_guides.js"],"mappings":"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","ignoreList":[]}
|
||||
2
core/bitrix/js/landing/ui/field/aha_guides.min.js
vendored
Normal file
2
core/bitrix/js/landing/ui/field/aha_guides.min.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
(function(){"use strict";BX.namespace("BX.Landing.UI.Guide");BX.Landing.UI.Guide.TourManager=class e{registeredGuides=new Map;observer=null;register(e){this.registeredGuides.set(e.id,e);if(!this.observer){this.startObserving()}}startObserving(){if(this.observer){return}this.observer=new MutationObserver(this.#e.bind(this));this.observer.observe(document.body,{childList:true,subtree:true})}#e(e){for(const t of e){if(t.type==="childList"){t.addedNodes.forEach(this.#t.bind(this))}}}#t(e){if(e.nodeType===Node.ELEMENT_NODE){this.checkNodeForTargets(e)}}stopObserving(){if(this.observer){this.observer.disconnect();this.observer=null}}checkNodeForTargets(e){for(const[t,n]of this.registeredGuides){try{const i=e.matches(n.selector)?e:e.querySelector(n.selector);if(!i){continue}if(n.requiredChildSelector){const e=i.querySelector(n.requiredChildSelector);if(!e){continue}}this.processGuide(t,n,i)}catch(e){}}}async processGuide(e,t,n){this.registeredGuides.delete(e);try{const e=await t.checkCondition();if(!e){return}await t.showGuide(n);if(t.markAsShown){t.markAsShown()}}catch(e){}finally{if(this.registeredGuides.size===0){this.stopObserving()}}}};const e=new BX.Landing.UI.Guide.TourManager;BX.ready((()=>{if(!BX.UI?.Tour?.Guide||!BX.Event){return}const t=BX.UI.Tour.Guide;const n=BX.Event;function i(){return new Promise((e=>{BX.ajax.runAction("landing.landing.isPhoneRegionCodeTourAlreadySeen").then((t=>{e(t.data)}),(()=>{e(false)})).catch((()=>{e(false)}))}))}function o(){BX.userOptions.save("ui-tour","landing_phone_aha_shown","null","Y")}function s(e){return new Promise((i=>{try{const o=e.querySelector(".landing-ui-button-icon-edit");const s=new t({id:"landing-phone-field-aha-moment",overlay:true,simpleMode:true,onEvents:false,steps:[{target:e,title:"",text:BX.Landing.Loc.getMessage("LANDING_PHONE_FIELD_AHA_MOMENT_REGION_CODE"),position:"bottom"}]});s.getPopup().setWidth(350);const r=()=>{const t=s.getPopup();if(!t||!t.getPopupContainer()){return}const n=t.getPopupContainer();const i=e.getBoundingClientRect();const r=i.right-n.offsetWidth;BX.Dom.style(n,{left:`${r}px`});const d=t.angle?.element;if(d&&o){const e=o.getBoundingClientRect();const t=e.left+e.width/2;const n=t-r;const i=d.offsetWidth;BX.Dom.style(d,{left:`${n-i/2}px`})}};const d=()=>{n.unbind(window,"resize",r);n.unbind(document,"scroll",r,true);i()};s.getPopup().subscribe("onClose",d);s.getPopup().subscribe("onDestroy",d);s.start();requestAnimationFrame((()=>{const e=s.getPopup().getPopupContainer();if(e){BX.Dom.style(e,{zIndex:"1050"})}}));requestAnimationFrame((()=>{r()}));n.bind(window,"resize",r);n.bind(document,"scroll",r,true);i()}catch(e){i()}}))}e.register({id:"landing-phone-field-aha",selector:'.landing-ui-component-list-item[data-type="phone"]',requiredChildSelector:".landing-ui-button-icon-edit",checkCondition:async()=>{const e=await i();return!e},showGuide:s,markAsShown:o})}))})();
|
||||
//# sourceMappingURL=aha_guides.map.js
|
||||
@@ -5,7 +5,7 @@ $MESS["LANDING_FIELD_COLOR-BG_FIXED"] = "Fixiert";
|
||||
$MESS["LANDING_FIELD_COLOR-BG_IMAGE"] = "Bild";
|
||||
$MESS["LANDING_FIELD_COLOR-BG_MOSAIC"] = "Kacheln";
|
||||
$MESS["LANDING_FIELD_COLOR-BG_OVERLAY"] = "Farbüberlagerung";
|
||||
$MESS["LANDING_FIELD_COLOR-BG_SIZE_TITLE"] = "Bildmodus";
|
||||
$MESS["LANDING_FIELD_COLOR-BG_SIZE_TITLE"] = "Bildmodus:";
|
||||
$MESS["LANDING_FIELD_COLOR-BUTTON_CANCEL"] = "Abbrechen";
|
||||
$MESS["LANDING_FIELD_COLOR-BUTTON_SELECT"] = "Auswählen";
|
||||
$MESS["LANDING_FIELD_COLOR-GRADIENT_DO_LINEAR"] = "Linear gestalten";
|
||||
|
||||
@@ -5,7 +5,7 @@ $MESS["LANDING_FIELD_COLOR-BG_FIXED"] = "Fixed";
|
||||
$MESS["LANDING_FIELD_COLOR-BG_IMAGE"] = "Image";
|
||||
$MESS["LANDING_FIELD_COLOR-BG_MOSAIC"] = "Tile";
|
||||
$MESS["LANDING_FIELD_COLOR-BG_OVERLAY"] = "Color overlay";
|
||||
$MESS["LANDING_FIELD_COLOR-BG_SIZE_TITLE"] = "Image mode";
|
||||
$MESS["LANDING_FIELD_COLOR-BG_SIZE_TITLE"] = "Image mode:";
|
||||
$MESS["LANDING_FIELD_COLOR-BUTTON_CANCEL"] = "Cancel";
|
||||
$MESS["LANDING_FIELD_COLOR-BUTTON_SELECT"] = "Select";
|
||||
$MESS["LANDING_FIELD_COLOR-GRADIENT_DO_LINEAR"] = "Make linear";
|
||||
|
||||
@@ -33,3 +33,4 @@ $MESS["LANDING_FIELDS_LIST_FIELD_PRODUCTS_TITLE2"] = "Produktliste";
|
||||
$MESS["LANDING_FIELDS_LIST_FIELD_SEPARATOR_TITLE"] = "Trennzeichen";
|
||||
$MESS["LANDING_FIELDS_SELECT_PRODUCTS_BUTTON_TITLE"] = "Produkte hinzufugen";
|
||||
$MESS["LANDING_FIELDS_SELECT_SEPARATOR_BUTTON_TITLE"] = "Trennzeichen hinzufügen";
|
||||
$MESS["LANDING_PHONE_FIELD_AHA_MOMENT_REGION_CODE"] = "Sie können auch das Feld des Ländecodes hinzufügen. Nutzer müssen es nicht manuell eingeben, was Fehler reduziert.";
|
||||
|
||||
@@ -33,3 +33,4 @@ $MESS["LANDING_FIELDS_LIST_FIELD_PRODUCTS_TITLE2"] = "Product list";
|
||||
$MESS["LANDING_FIELDS_LIST_FIELD_SEPARATOR_TITLE"] = "Separator";
|
||||
$MESS["LANDING_FIELDS_SELECT_PRODUCTS_BUTTON_TITLE"] = "Add products";
|
||||
$MESS["LANDING_FIELDS_SELECT_SEPARATOR_BUTTON_TITLE"] = "Add separator";
|
||||
$MESS["LANDING_PHONE_FIELD_AHA_MOMENT_REGION_CODE"] = "You may opt to add the country code field. Users won't have to enter it manually which will reduce errors.";
|
||||
|
||||
@@ -33,3 +33,4 @@ $MESS["LANDING_FIELDS_LIST_FIELD_PRODUCTS_TITLE2"] = "Тауарлар тізі
|
||||
$MESS["LANDING_FIELDS_LIST_FIELD_SEPARATOR_TITLE"] = "Бөлгіш";
|
||||
$MESS["LANDING_FIELDS_SELECT_PRODUCTS_BUTTON_TITLE"] = "Тауарларды қосу";
|
||||
$MESS["LANDING_FIELDS_SELECT_SEPARATOR_BUTTON_TITLE"] = "Бөлгішті қосу";
|
||||
$MESS["LANDING_PHONE_FIELD_AHA_MOMENT_REGION_CODE"] = "Ел кодын қосыңыз — ол нысанға автоматты түрде жазылады. Осылайша, клиенттерге нөмірді енгізу оңайырақ болады және сіз байланыс үшін дұрыс телефон аласыз.";
|
||||
|
||||
@@ -40,4 +40,5 @@ $MESS['LANDING_FIELDS_ITEM_ENABLE_HINT_ON_FOCUS'] = 'Включить подск
|
||||
$MESS['LANDING_FIELDS_ITEM_FORM_ALLOWED_ANY_FILE_TYPE'] = 'Любые';
|
||||
|
||||
$MESS['LANDING_FIELDS_ITEM_REQUISITE_SETTINGS_LABEL'] = 'Настройка реквизитов';
|
||||
$MESS['LANDING_FIELDS_ITEM_REQUISITE_SETTINGS_FIELDS_LABEL'] = 'настроить поля';
|
||||
$MESS['LANDING_FIELDS_ITEM_REQUISITE_SETTINGS_FIELDS_LABEL'] = 'настроить поля';
|
||||
$MESS['LANDING_PHONE_FIELD_AHA_MOMENT_REGION_CODE'] = 'Добавьте код страны — он будет подставляться в форму автоматически. Так клиентам будет проще вводить номер, а вы получите правильный телефон для связи';
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
;(function() {
|
||||
"use strict";
|
||||
|
||||
BX.namespace("BX.Landing.UI.Field");
|
||||
|
||||
var clone = BX.Landing.Utils.clone;
|
||||
|
||||
|
||||
/**
|
||||
* Implements interface for works with Icon field
|
||||
*
|
||||
* @extends {BX.Landing.UI.Field.Image}
|
||||
*
|
||||
* @inheritDoc
|
||||
* @constructor
|
||||
*/
|
||||
BX.Landing.UI.Field.Icon = function(data)
|
||||
{
|
||||
BX.Landing.UI.Field.Image.apply(this, arguments);
|
||||
this.uploadButton.layout.innerText = BX.Landing.Loc.getMessage("LANDING_ICONS_FIELD_BUTTON_REPLACE");
|
||||
this.editButton.layout.hidden = true;
|
||||
this.clearButton.layout.hidden = true;
|
||||
|
||||
this.dropzone.removeEventListener("dragover", this.onDragOver);
|
||||
this.dropzone.removeEventListener("dragleave", this.onDragLeave);
|
||||
this.dropzone.removeEventListener("drop", this.onDrop);
|
||||
this.preview.removeEventListener("dragenter", this.onImageDragEnter);
|
||||
|
||||
BX.Landing.UI.Panel.IconPanel
|
||||
.getLibraries()
|
||||
.then(function(libraries) {
|
||||
if (libraries.length === 0)
|
||||
{
|
||||
this.uploadButton.disable();
|
||||
}
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
BX.Landing.UI.Field.Icon.prototype = {
|
||||
constructor: BX.Landing.UI.Field.Icon,
|
||||
__proto__: BX.Landing.UI.Field.Image.prototype,
|
||||
|
||||
onUploadClick: function(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
|
||||
BX.Landing.UI.Panel.IconPanel
|
||||
.getInstance()
|
||||
.show()
|
||||
.then(function(iconClassName) {
|
||||
this.setValue({type: "icon", classList: iconClassName.split(" ")});
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return {boolean}
|
||||
*/
|
||||
isChanged: function()
|
||||
{
|
||||
return this.getValue().classList.some(function(className) {
|
||||
return this.content.classList.indexOf(className) === -1;
|
||||
}, this);
|
||||
},
|
||||
|
||||
getValue: function()
|
||||
{
|
||||
var classList = this.classList;
|
||||
|
||||
if (this.selector)
|
||||
{
|
||||
var selectorClassname = this.selector.split("@")[0].replace(".", "");
|
||||
classList = clone(this.classList).concat([selectorClassname]);
|
||||
classList = BX.Landing.Utils.arrayUnique(classList);
|
||||
}
|
||||
|
||||
return {
|
||||
type: "icon",
|
||||
src: "",
|
||||
id: -1,
|
||||
alt: "",
|
||||
classList: classList,
|
||||
url: Object.assign({}, this.url.getValue(), {enabled: this.urlCheckbox.checked})
|
||||
};
|
||||
},
|
||||
|
||||
reset: function()
|
||||
{
|
||||
this.setValue({
|
||||
type: "icon",
|
||||
src: "",
|
||||
id: -1,
|
||||
alt: "",
|
||||
classList: [],
|
||||
url: ''
|
||||
})
|
||||
}
|
||||
};
|
||||
})();
|
||||
@@ -1,997 +0,0 @@
|
||||
;(function() {
|
||||
"use strict";
|
||||
|
||||
BX.namespace("BX.Landing.UI.Field");
|
||||
|
||||
var isPlainObject = BX.Landing.Utils.isPlainObject;
|
||||
var isNumber = BX.Landing.Utils.isNumber;
|
||||
var isEmpty = BX.Landing.Utils.isEmpty;
|
||||
var isString = BX.Landing.Utils.isString;
|
||||
var decodeDataValue = BX.Landing.Utils.decodeDataValue;
|
||||
var clone = BX.Landing.Utils.clone;
|
||||
var create = BX.Landing.Utils.create;
|
||||
var fireCustomEvent = BX.Landing.Utils.fireCustomEvent;
|
||||
|
||||
/**
|
||||
* Implements interface for works with image field in editor
|
||||
*
|
||||
* @extends {BX.Landing.UI.Field.Text}
|
||||
*
|
||||
* @param {object} data
|
||||
* @constructor
|
||||
*/
|
||||
BX.Landing.UI.Field.Image = function(data)
|
||||
{
|
||||
BX.Landing.UI.Field.Text.apply(this, arguments);
|
||||
|
||||
this.dimensions = typeof data.dimensions === "object" ? data.dimensions : null;
|
||||
this.create2xByDefault = data.create2xByDefault !== false;
|
||||
this.uploadParams = typeof data.uploadParams === "object" ? data.uploadParams : {};
|
||||
this.onValueChangeHandler = data.onValueChange ? data.onValueChange : (function() {});
|
||||
this.type = this.content.type || "image";
|
||||
this.allowClear = data.allowClear;
|
||||
this.input.innerText = this.content.src;
|
||||
this.input.hidden = true;
|
||||
this.input2x = this.createInput();
|
||||
this.input2x.innerText = this.content.src2x;
|
||||
this.input2x.hidden = true;
|
||||
|
||||
this.layout.classList.add("landing-ui-field-image");
|
||||
if (data.compactMode === true)
|
||||
{
|
||||
this.layout.classList.add("landing-ui-field-image--compact");
|
||||
}
|
||||
|
||||
this.disableAltField = typeof data.disableAltField === "boolean" ? data.disableAltField : false;
|
||||
|
||||
this.fileInput = createFileInput(this.selector);
|
||||
this.fileInput.addEventListener("change", this.onFileInputChange.bind(this));
|
||||
|
||||
this.linkInput = createLinkInput();
|
||||
this.linkInput.onInputHandler = this.onLinkInput.bind(this);
|
||||
|
||||
this.dropzone = createDropzone(this.selector);
|
||||
this.dropzone.hidden = true;
|
||||
this.dropzone.insertBefore(this.fileInput, this.dropzone.firstElementChild);
|
||||
|
||||
this.onDragOver = this.onDragOver.bind(this);
|
||||
this.onDragLeave = this.onDragLeave.bind(this);
|
||||
this.onDrop = this.onDrop.bind(this);
|
||||
|
||||
this.dropzone.addEventListener("dragover", this.onDragOver);
|
||||
this.dropzone.addEventListener("dragleave", this.onDragLeave);
|
||||
this.dropzone.addEventListener("drop", this.onDrop);
|
||||
|
||||
this.clearButton = createClearButton();
|
||||
this.clearButton.on("click", this.onClearClick.bind(this));
|
||||
|
||||
this.preview = createImagePreview();
|
||||
this.preview.appendChild(this.clearButton.layout);
|
||||
this.preview.style.backgroundImage = "url("+this.input.innerText.trim()+")";
|
||||
|
||||
this.onImageDragEnter = this.onImageDragEnter.bind(this);
|
||||
this.preview.addEventListener("dragenter", this.onImageDragEnter);
|
||||
|
||||
this.loader = new BX.Loader({target: this.preview});
|
||||
|
||||
this.icon = createIcon();
|
||||
|
||||
this.image = createImageLayout();
|
||||
this.image.appendChild(this.preview);
|
||||
this.image.appendChild(this.icon);
|
||||
this.image.dataset.fileid = this.content.id;
|
||||
this.image.dataset.fileid2x = this.content.id2x;
|
||||
|
||||
this.hiddenImage = create("img", {
|
||||
props: {className: "landing-ui-field-image-hidden"}
|
||||
});
|
||||
|
||||
if (isPlainObject(this.content) && "src" in this.content)
|
||||
{
|
||||
this.hiddenImage.src = this.content.src;
|
||||
}
|
||||
|
||||
this.altField = createAltField();
|
||||
this.altField.setValue(this.content.alt);
|
||||
|
||||
this.left = createLeftLayout();
|
||||
this.left.appendChild(this.dropzone);
|
||||
this.left.appendChild(this.image);
|
||||
this.left.appendChild(this.hiddenImage);
|
||||
|
||||
if (this.description)
|
||||
{
|
||||
this.left.appendChild(this.description);
|
||||
}
|
||||
|
||||
this.left.appendChild(this.altField.layout);
|
||||
this.left.appendChild(this.linkInput.layout);
|
||||
|
||||
this.uploadButton = createUploadButton();
|
||||
this.uploadButton.on("click", this.onUploadClick.bind(this));
|
||||
|
||||
this.editButton = createEditButton();
|
||||
this.editButton.on("click", this.onEditClick.bind(this));
|
||||
|
||||
this.right = createRightLayout();
|
||||
this.right.appendChild(this.uploadButton.layout);
|
||||
this.right.appendChild(this.editButton.layout);
|
||||
|
||||
|
||||
this.form = createForm();
|
||||
this.form.appendChild(this.left);
|
||||
this.form.appendChild(this.right);
|
||||
|
||||
this.layout.appendChild(this.form);
|
||||
|
||||
this.enableTextOnly();
|
||||
|
||||
if (!this.input.innerText.trim() || this.input.innerText.trim() === window.location.toString())
|
||||
{
|
||||
this.showDropzone();
|
||||
}
|
||||
|
||||
if (this.disableAltField)
|
||||
{
|
||||
this.altField.layout.hidden = true;
|
||||
this.altField.layout.style.display = "none";
|
||||
this.altField.layout.classList.add("landing-ui-hide");
|
||||
}
|
||||
|
||||
if (this.content.type === "icon")
|
||||
{
|
||||
this.type = "icon";
|
||||
this.classList = this.content.classList;
|
||||
var sourceClassList = this.content.classList;
|
||||
var newClassList = [];
|
||||
|
||||
BX.Landing.UI.Panel.IconPanel
|
||||
.getLibraries()
|
||||
.then(function(libraries) {
|
||||
libraries.forEach(function(library) {
|
||||
library.categories.forEach(function(category) {
|
||||
category.items.forEach(function(item) {
|
||||
var classList = item.split(" ");
|
||||
classList.forEach(function(className) {
|
||||
if (sourceClassList.indexOf(className) !== -1 && newClassList.indexOf(className) === -1)
|
||||
{
|
||||
newClassList.push(className);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
this.icon.innerHTML = "<span class=\""+newClassList.join(" ")+"\"></span>";
|
||||
}.bind(this));
|
||||
|
||||
this.showPreview();
|
||||
this.altField.layout.hidden = true;
|
||||
}
|
||||
|
||||
this.makeAsLinkWrapper = create("div", {
|
||||
props: {className: "landing-ui-field-image-make-as-link-wrapper"},
|
||||
children: [
|
||||
create('div', {
|
||||
props: {className: "landing-ui-field-image-make-as-link-button"},
|
||||
children: [
|
||||
|
||||
]
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
this.url = new BX.Landing.UI.Field.Link({
|
||||
content: this.content.url || {
|
||||
text: '',
|
||||
href: ''
|
||||
},
|
||||
options: {
|
||||
siteId: BX.Landing.Main.getInstance().options.site_id,
|
||||
landingId: BX.Landing.Main.getInstance().id
|
||||
},
|
||||
contentRoot: this.contentRoot
|
||||
});
|
||||
|
||||
this.urlCheckbox = create("input", {
|
||||
props: {type: "checkbox"},
|
||||
attrs: {style: "margin-left: 4px;"}
|
||||
});
|
||||
|
||||
function onCheckboxChange(checkbox, layout) {
|
||||
if (checkbox.checked)
|
||||
{
|
||||
layout.querySelector(".landing-ui-field-link-right").classList.remove("landing-ui-disabled");
|
||||
layout.querySelector(".landing-ui-field-link-url-grid").classList.remove("landing-ui-disabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
layout.querySelector(".landing-ui-field-link-right").classList.add("landing-ui-disabled");
|
||||
layout.querySelector(".landing-ui-field-link-url-grid").classList.add("landing-ui-disabled");
|
||||
}
|
||||
}
|
||||
|
||||
this.urlCheckbox.addEventListener('change', function() {
|
||||
onCheckboxChange(this.urlCheckbox, this.url.layout);
|
||||
}.bind(this));
|
||||
|
||||
this.urlCheckbox.checked = this.content.url && this.content.url.enabled;
|
||||
|
||||
onCheckboxChange(this.urlCheckbox, this.url.layout);
|
||||
|
||||
this.url.hrefInput.header.appendChild(this.urlCheckbox);
|
||||
this.url.left.hidden = true;
|
||||
|
||||
this.makeAsLinkWrapper.appendChild(this.url.layout);
|
||||
|
||||
if (!data.disableLink)
|
||||
{
|
||||
this.layout.appendChild(this.makeAsLinkWrapper);
|
||||
}
|
||||
|
||||
this.content = this.getValue();
|
||||
BX.DOM.write(function() {
|
||||
this.adjustPreviewBackgroundSize();
|
||||
}.bind(this));
|
||||
|
||||
if (this.getValue().type === "background" || this.allowClear)
|
||||
{
|
||||
this.clearButton.layout.classList.add("landing-ui-show");
|
||||
}
|
||||
|
||||
this.uploader = new BX.Landing.ImageUploader({
|
||||
uploadParams: this.uploadParams,
|
||||
additionalParams: {context: 'imageeditor'},
|
||||
dimensions: this.dimensions,
|
||||
sizes: ['1x', '2x']
|
||||
});
|
||||
|
||||
this.adjustEditButtonState();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates file input
|
||||
* @return {Element}
|
||||
*/
|
||||
function createFileInput(id)
|
||||
{
|
||||
return BX.create("input", {
|
||||
props: {className: "landing-ui-field-image-dropzone-input"},
|
||||
attrs: {accept: "image/*", type: "file", id: "file_" + id, name: "picture"}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates link input field
|
||||
* @return {BX.Landing.UI.Field.Text}
|
||||
*/
|
||||
function createLinkInput()
|
||||
{
|
||||
var field = new BX.Landing.UI.Field.Text({
|
||||
id: "path_to_image",
|
||||
placeholder: BX.Landing.Loc.getMessage("LANDING_IMAGE_UPLOAD_MENU_LINK_LABEL")
|
||||
});
|
||||
field.enableTextOnly();
|
||||
field.layout.hidden = true;
|
||||
return field;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates dropzone
|
||||
* @param {string} id
|
||||
* @return {Element}
|
||||
*/
|
||||
function createDropzone(id)
|
||||
{
|
||||
return BX.create("label", {
|
||||
props: {className: "landing-ui-field-image-dropzone"},
|
||||
children: [
|
||||
BX.create("div", {
|
||||
props: {className: "landing-ui-field-image-dropzone-text"},
|
||||
html: (
|
||||
"<div class=\"landing-ui-field-image-dropzone-title\">"+BX.Landing.Loc.getMessage("LANDING_IMAGE_DROPZONE_TITLE")+"</div>" +
|
||||
"<div class=\"landing-ui-field-image-dropzone-subtitle\">"+BX.Landing.Loc.getMessage("LANDING_IMAGE_DROPZONE_SUBTITLE")+"</div>"
|
||||
)
|
||||
})
|
||||
],
|
||||
attrs: {"for": "file_" + id}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates clear button
|
||||
* @return {BX.Landing.UI.Button.BaseButton}
|
||||
*/
|
||||
function createClearButton()
|
||||
{
|
||||
return new BX.Landing.UI.Button.BaseButton("clear", {
|
||||
className: "landing-ui-field-image-action-button-clear"
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates image preview
|
||||
* @return {Element}
|
||||
*/
|
||||
function createImagePreview()
|
||||
{
|
||||
return BX.create("div", {
|
||||
props: {className: "landing-ui-field-image-preview-inner"}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates icon layout
|
||||
* @return {Element}
|
||||
*/
|
||||
function createIcon()
|
||||
{
|
||||
return BX.create("span", {
|
||||
props: {className: "landing-ui-field-image-preview-icon"}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates image layout
|
||||
* @return {Element}
|
||||
*/
|
||||
function createImageLayout()
|
||||
{
|
||||
return BX.create("div", {
|
||||
props: {className: "landing-ui-field-image-preview"}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates alt field
|
||||
* @return {BX.Landing.UI.Field.Text}
|
||||
*/
|
||||
function createAltField()
|
||||
{
|
||||
var field = new BX.Landing.UI.Field.Text({
|
||||
placeholder: BX.Landing.Loc.getMessage("LANDING_FIELD_IMAGE_ALT_PLACEHOLDER"),
|
||||
className: "landing-ui-field-image-alt",
|
||||
textOnly: true
|
||||
});
|
||||
return field;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates left layout
|
||||
* @return {Element}
|
||||
*/
|
||||
function createLeftLayout()
|
||||
{
|
||||
return BX.create("div", {
|
||||
props: {className: "landing-ui-field-image-left"}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates upload button
|
||||
* @return {BX.Landing.UI.Button.BaseButton}
|
||||
*/
|
||||
function createUploadButton()
|
||||
{
|
||||
return new BX.Landing.UI.Button.BaseButton("upload", {
|
||||
text: BX.Landing.Loc.getMessage("LANDING_FIELD_IMAGE_UPLOAD_BUTTON"),
|
||||
className: "landing-ui-field-image-action-button"
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates edit button
|
||||
* @return {BX.Landing.UI.Button.BaseButton}
|
||||
*/
|
||||
function createEditButton()
|
||||
{
|
||||
var field = new BX.Landing.UI.Button.BaseButton("edit", {
|
||||
text: BX.Landing.Loc.getMessage("LANDING_FIELD_IMAGE_EDIT_BUTTON"),
|
||||
className: "landing-ui-field-image-action-button",
|
||||
});
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates right layout
|
||||
* @return {Element}
|
||||
*/
|
||||
function createRightLayout()
|
||||
{
|
||||
return BX.create("div", {
|
||||
props: {className: "landing-ui-field-image-right"}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates form
|
||||
* @return {Element}
|
||||
*/
|
||||
function createForm()
|
||||
{
|
||||
return BX.create("form", {
|
||||
props: {className: "landing-ui-field-image-container"},
|
||||
attrs: {method: "post", enctype: "multipart/form-data"},
|
||||
events: {
|
||||
submit: function(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
BX.Landing.UI.Field.Image.prototype = {
|
||||
constructor: BX.Landing.UI.Field.Image,
|
||||
__proto__: BX.Landing.UI.Field.Text.prototype,
|
||||
superClass: BX.Landing.UI.Field.Text,
|
||||
/**
|
||||
* Handles input event on input field
|
||||
*/
|
||||
onInputInput: function()
|
||||
{
|
||||
this.preview.src = this.input.innerText.trim();
|
||||
},
|
||||
|
||||
onImageDragEnter: function(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
if (!this.imageHidden)
|
||||
{
|
||||
this.showDropzone();
|
||||
this.imageHidden = true;
|
||||
}
|
||||
},
|
||||
|
||||
onDragOver: function(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.dropzone.classList.add("landing-ui-active");
|
||||
},
|
||||
|
||||
onDragLeave: function(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.dropzone.classList.remove("landing-ui-active");
|
||||
|
||||
if (this.imageHidden)
|
||||
{
|
||||
this.imageHidden = false;
|
||||
this.showPreview();
|
||||
}
|
||||
},
|
||||
|
||||
onDrop: function(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.dropzone.classList.remove("landing-ui-active");
|
||||
this.onFileChange(event.dataTransfer.files[0]);
|
||||
this.imageHidden = false;
|
||||
},
|
||||
|
||||
onFileChange: function(file)
|
||||
{
|
||||
this.showLoader();
|
||||
|
||||
this.upload(file)
|
||||
.then(this.setValue.bind(this))
|
||||
.then(this.hideLoader.bind(this))
|
||||
.catch(function(err) {
|
||||
console.error(err);
|
||||
this.hideLoader();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
onFileInputChange: function(event)
|
||||
{
|
||||
this.onFileChange(event.currentTarget.files[0]);
|
||||
},
|
||||
|
||||
onUploadClick: function(event)
|
||||
{
|
||||
this.bindElement = event.currentTarget;
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if (!this.uploadMenu)
|
||||
{
|
||||
this.uploadMenu = BX.Main.MenuManager.create({
|
||||
id: "upload_" + this.selector + (+new Date()),
|
||||
bindElement: this.bindElement,
|
||||
bindOptions: {
|
||||
forceBindPosition: true
|
||||
},
|
||||
items: [
|
||||
{
|
||||
text: BX.Landing.Loc.getMessage("LANDING_IMAGE_UPLOAD_MENU_UNSPLASH"),
|
||||
onclick: this.onUnsplashShow.bind(this)
|
||||
},
|
||||
{
|
||||
text: BX.Landing.Loc.getMessage("LANDING_IMAGE_UPLOAD_MENU_GOOGLE"),
|
||||
onclick: this.onGoogleShow.bind(this)
|
||||
},
|
||||
// {
|
||||
// text: BX.Landing.Loc.getMessage("LANDING_IMAGE_UPLOAD_MENU_PARTNER"),
|
||||
// className: "landing-ui-disabled"
|
||||
// },
|
||||
{
|
||||
text: BX.Landing.Loc.getMessage("LANDING_IMAGE_UPLOAD_MENU_UPLOAD"),
|
||||
onclick: this.onUploadShow.bind(this)
|
||||
},
|
||||
{
|
||||
text: BX.Landing.Loc.getMessage("LANDING_IMAGE_UPLOAD_MENU_LINK"),
|
||||
onclick: this.onLinkShow.bind(this)
|
||||
}
|
||||
],
|
||||
events: {
|
||||
onPopupClose: function ()
|
||||
{
|
||||
this.bindElement.classList.remove("landing-ui-active");
|
||||
|
||||
if (this.uploadMenu)
|
||||
{
|
||||
this.uploadMenu.destroy();
|
||||
this.uploadMenu = null;
|
||||
}
|
||||
}.bind(this)
|
||||
},
|
||||
targetContainer: this.contentRoot
|
||||
});
|
||||
if (!this.contentRoot)
|
||||
{
|
||||
this.bindElement.parentNode.appendChild(this.uploadMenu.popupWindow.popupContainer);
|
||||
}
|
||||
}
|
||||
|
||||
this.bindElement.classList.add("landing-ui-active");
|
||||
this.uploadMenu.toggle();
|
||||
|
||||
if (!this.contentRoot)
|
||||
{
|
||||
var rect = BX.pos(this.bindElement, this.bindElement.parentNode);
|
||||
this.uploadMenu.popupWindow.popupContainer.style.top = rect.bottom + "px";
|
||||
this.uploadMenu.popupWindow.popupContainer.style.left = "auto";
|
||||
this.uploadMenu.popupWindow.popupContainer.style.right = "5px";
|
||||
}
|
||||
},
|
||||
|
||||
onUnsplashShow: function()
|
||||
{
|
||||
this.uploadMenu.close();
|
||||
|
||||
BX.Landing.UI.Panel.Image.getInstance()
|
||||
.show("unsplash", this.dimensions, this.loader, this.uploadParams)
|
||||
.then(this.upload.bind(this))
|
||||
.then(this.setValue.bind(this))
|
||||
.then(this.hideLoader.bind(this))
|
||||
.catch(function(err) {
|
||||
console.error(err);
|
||||
this.hideLoader();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
onGoogleShow: function()
|
||||
{
|
||||
this.uploadMenu.close();
|
||||
|
||||
BX.Landing.UI.Panel.Image.getInstance()
|
||||
.show("google", this.dimensions, this.loader, this.uploadParams)
|
||||
.then(this.upload.bind(this))
|
||||
.then(this.setValue.bind(this))
|
||||
.then(this.hideLoader.bind(this))
|
||||
.catch(function(err) {
|
||||
BX.Landing.ErrorManager.getInstance().add({
|
||||
type: 'error',
|
||||
action: 'BAD_IMAGE',
|
||||
hideSupportLink: true,
|
||||
});
|
||||
console.error(err);
|
||||
this.hideLoader();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
onUploadShow: function()
|
||||
{
|
||||
this.uploadMenu.close();
|
||||
this.fileInput.click();
|
||||
},
|
||||
|
||||
onLinkShow: function()
|
||||
{
|
||||
this.uploadMenu.close();
|
||||
this.showLinkField();
|
||||
this.linkInput.setValue("");
|
||||
},
|
||||
|
||||
onEditClick: function(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
this.edit({src: this.hiddenImage.src});
|
||||
},
|
||||
|
||||
onClearClick: function(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
this.setValue({src: ""});
|
||||
this.fileInput.value = "";
|
||||
this.showDropzone();
|
||||
},
|
||||
|
||||
showDropzone: function()
|
||||
{
|
||||
this.dropzone.hidden = false;
|
||||
this.image.hidden = true;
|
||||
this.altField.layout.hidden = true;
|
||||
this.linkInput.layout.hidden = true;
|
||||
},
|
||||
|
||||
showPreview: function()
|
||||
{
|
||||
this.dropzone.hidden = true;
|
||||
this.image.hidden = false;
|
||||
this.altField.layout.hidden = false;
|
||||
this.linkInput.layout.hidden = true;
|
||||
},
|
||||
|
||||
showLinkField: function()
|
||||
{
|
||||
this.dropzone.hidden = true;
|
||||
this.image.hidden = true;
|
||||
this.altField.layout.hidden = true;
|
||||
this.linkInput.layout.hidden = false;
|
||||
},
|
||||
|
||||
|
||||
onLinkInput: function(value)
|
||||
{
|
||||
var tmpImage = BX.create("img");
|
||||
tmpImage.src = value;
|
||||
tmpImage.onload = function() {
|
||||
this.showPreview();
|
||||
this.setValue({src: value, src2x: value});
|
||||
}.bind(this);
|
||||
},
|
||||
|
||||
showLoader: function()
|
||||
{
|
||||
if (this.dropzone && !this.dropzone.hidden)
|
||||
{
|
||||
this.loader.show(this.dropzone);
|
||||
return;
|
||||
}
|
||||
|
||||
this.loader.show(this.preview);
|
||||
},
|
||||
|
||||
|
||||
hideLoader: function()
|
||||
{
|
||||
this.loader.hide();
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Handles click event on input field
|
||||
* @param {MouseEvent} event
|
||||
*/
|
||||
onInputClick: function(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @return {boolean}
|
||||
*/
|
||||
isChanged: function()
|
||||
{
|
||||
var lastValue = clone(this.content);
|
||||
var currentValue = clone(this.getValue());
|
||||
|
||||
if (lastValue.url && isString(lastValue.url))
|
||||
{
|
||||
lastValue.url = decodeDataValue(lastValue.url);
|
||||
}
|
||||
|
||||
if (currentValue.url && isString(currentValue.url))
|
||||
{
|
||||
currentValue.url = decodeDataValue(currentValue.url);
|
||||
}
|
||||
|
||||
return JSON.stringify(lastValue) !== JSON.stringify(currentValue);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Adjusts preview background image size
|
||||
*/
|
||||
adjustPreviewBackgroundSize: function()
|
||||
{
|
||||
var img = BX.create("img", {attrs: {src: this.getValue().src}});
|
||||
|
||||
img.onload = function()
|
||||
{
|
||||
var preview = this.preview.getBoundingClientRect();
|
||||
var position = "cover";
|
||||
|
||||
if (img.width > preview.width || img.height > preview.height)
|
||||
{
|
||||
position = "contain";
|
||||
}
|
||||
|
||||
if (img.width < preview.width && img.height < preview.height)
|
||||
{
|
||||
position = "auto";
|
||||
}
|
||||
|
||||
BX.DOM.write(function() {
|
||||
this.preview.style.backgroundSize = position;
|
||||
}.bind(this));
|
||||
}.bind(this);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @param {object} value
|
||||
* @param {boolean} [preventEvent = false]
|
||||
*/
|
||||
setValue: function(value, preventEvent)
|
||||
{
|
||||
if (value.type !== "icon")
|
||||
{
|
||||
if (!value || !value.src)
|
||||
{
|
||||
this.input.innerText = "";
|
||||
this.input2x.innerText = "";
|
||||
this.preview.removeAttribute("style");
|
||||
this.input.dataset.ext = "";
|
||||
this.showDropzone();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.input.innerText = value.src;
|
||||
this.input2x.innerText = value.src2x || '';
|
||||
this.preview.style.backgroundImage = "url(\""+(value.src2x || value.src)+"\")";
|
||||
this.preview.id = BX.util.getRandomString();
|
||||
this.hiddenImage.src = value.src2x || value.src;
|
||||
this.showPreview();
|
||||
}
|
||||
|
||||
this.image.dataset.fileid = value && value.id ? value.id : -1;
|
||||
this.image.dataset.fileid2x = value && value.id2x ? value.id2x : -1;
|
||||
|
||||
this.classList = [];
|
||||
}
|
||||
else
|
||||
{
|
||||
this.preview.style.backgroundImage = null;
|
||||
this.classList = value.classList;
|
||||
this.icon.innerHTML = "<span class=\""+value.classList.join(" ")+"\"></span>";
|
||||
this.showPreview();
|
||||
this.type = "icon";
|
||||
this.altField.layout.hidden = true;
|
||||
this.altField.setValue("");
|
||||
this.input.innerText = "";
|
||||
}
|
||||
|
||||
if (value.url)
|
||||
{
|
||||
this.url.setValue(value.url);
|
||||
}
|
||||
|
||||
this.adjustPreviewBackgroundSize();
|
||||
this.adjustEditButtonState();
|
||||
this.hideLoader();
|
||||
|
||||
this.onValueChangeHandler(this);
|
||||
BX.fireEvent(this.layout, "input");
|
||||
|
||||
var event = new BX.Event.BaseEvent({
|
||||
data: {value: this.getValue()},
|
||||
compatData: [this.getValue()],
|
||||
});
|
||||
if (!preventEvent)
|
||||
{
|
||||
this.emit('change', event);
|
||||
}
|
||||
},
|
||||
|
||||
adjustEditButtonState: function()
|
||||
{
|
||||
var value = this.getValue();
|
||||
if (BX.Type.isStringFilled(value.src))
|
||||
{
|
||||
this.editButton.enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.editButton.disable();
|
||||
}
|
||||
},
|
||||
|
||||
reset: function()
|
||||
{
|
||||
this.setValue({
|
||||
type: this.getValue().type,
|
||||
id: -1,
|
||||
src: "",
|
||||
alt: ""
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Gets field value
|
||||
* @return {{src, [alt]: string, [title]: string, [url]: string}}
|
||||
*/
|
||||
getValue: function()
|
||||
{
|
||||
var fileId = parseInt(this.image.dataset.fileid);
|
||||
var fileId2x = parseInt(this.image.dataset.fileid2x);
|
||||
fileId = fileId === fileId ? fileId : -1;
|
||||
fileId2x = fileId2x === fileId2x ? fileId2x : -1;
|
||||
|
||||
var value = {type: "", src: "", id: fileId, id2x: fileId2x, src2x: "", alt: "", url: ""};
|
||||
|
||||
if (this.type === "background")
|
||||
{
|
||||
value.type = "background";
|
||||
value.src = this.input.innerText.trim();
|
||||
value.src2x = this.input2x.innerText.trim();
|
||||
value.id = fileId;
|
||||
value.id2x = fileId2x;
|
||||
}
|
||||
|
||||
if (this.type === "image")
|
||||
{
|
||||
value.type = "image";
|
||||
value.src = this.input.innerText.trim();
|
||||
value.src2x = this.input2x.innerText.trim();
|
||||
value.id = fileId;
|
||||
value.id2x = fileId2x;
|
||||
value.alt = this.altField.getValue();
|
||||
}
|
||||
|
||||
if (this.type === "icon")
|
||||
{
|
||||
value.type = "icon";
|
||||
value.classList = this.classList;
|
||||
}
|
||||
|
||||
value.url = Object.assign({}, this.url.getValue(), {enabled: this.urlCheckbox.checked});
|
||||
|
||||
return value;
|
||||
},
|
||||
|
||||
edit: function(data)
|
||||
{
|
||||
BX.Landing.ImageEditor
|
||||
.edit({
|
||||
image: data.src,
|
||||
dimensions: this.dimensions
|
||||
})
|
||||
.then(function(file) {
|
||||
return this.upload(file, {context: "imageEditor"});
|
||||
}.bind(this))
|
||||
.then(function(result) {
|
||||
this.setValue(result);
|
||||
}.bind(this));
|
||||
|
||||
// Analytics hack
|
||||
var tmpImage = new Image();
|
||||
var imageSrc = "/bitrix/images/landing/close.svg";
|
||||
|
||||
imageSrc = BX.util.add_url_param(imageSrc, {
|
||||
action: "openImageEditor"
|
||||
});
|
||||
|
||||
tmpImage.src = imageSrc + "?" + (+new Date());
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {File|Blob} file
|
||||
* @param {object} [additionalParams]
|
||||
*/
|
||||
upload: function(file, additionalParams)
|
||||
{
|
||||
if (file.type && (file.type.includes('text') || file.type.includes('html')))
|
||||
{
|
||||
BX.Landing.ErrorManager.getInstance().add({
|
||||
type: "error",
|
||||
action: "BAD_IMAGE"
|
||||
});
|
||||
|
||||
return Promise.reject({
|
||||
type: "error",
|
||||
action: "BAD_IMAGE"
|
||||
});
|
||||
}
|
||||
|
||||
this.showLoader();
|
||||
|
||||
var checkSize = new Promise(function(resolve) {
|
||||
var sizes = ['1x', '2x'];
|
||||
|
||||
if (this.create2xByDefault === false)
|
||||
{
|
||||
var image = new Image();
|
||||
var objectUrl = URL.createObjectURL(file);
|
||||
var dimensions = this.dimensions;
|
||||
image.onload = function() {
|
||||
URL.revokeObjectURL(objectUrl);
|
||||
if (
|
||||
(
|
||||
this.width >= dimensions.width
|
||||
|| this.height >= dimensions.height
|
||||
|| this.width >= dimensions.maxWidth
|
||||
|| this.height >= dimensions.maxHeight
|
||||
) === false
|
||||
)
|
||||
{
|
||||
sizes = ['1x'];
|
||||
}
|
||||
|
||||
resolve(sizes);
|
||||
};
|
||||
image.src = objectUrl;
|
||||
}
|
||||
else
|
||||
{
|
||||
resolve(sizes);
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
return checkSize
|
||||
.then(function(allowedSizes) {
|
||||
var sizes = (function() {
|
||||
if (
|
||||
this.create2xByDefault === false
|
||||
&& BX.Type.isArrayFilled(allowedSizes)
|
||||
)
|
||||
{
|
||||
return allowedSizes;
|
||||
}
|
||||
|
||||
return ['1x', '2x'];
|
||||
}.bind(this))();
|
||||
|
||||
return this.uploader
|
||||
.setSizes(sizes)
|
||||
.upload(file, additionalParams)
|
||||
.then(function(result) {
|
||||
this.hideLoader();
|
||||
|
||||
if (sizes.length === 1)
|
||||
{
|
||||
return result[0];
|
||||
}
|
||||
|
||||
return Object.assign({}, result[0], {
|
||||
src2x: result[1].src,
|
||||
id2x: result[1].id
|
||||
});
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
}
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user