123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224 |
- (function($, FLBuilder) {
- /**
- * Polyfill for String.startsWith()
- */
- if (!String.prototype.startsWith) {
- String.prototype.startsWith = function(searchString, position){
- position = position || 0;
- return this.substr(position, searchString.length) === searchString;
- };
- }
- /**
- * Polyfill for String.endsWidth()
- */
- if (!String.prototype.endsWith) {
- String.prototype.endsWith = function(searchString, position) {
- var subjectString = this.toString();
- if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
- position = subjectString.length;
- }
- position -= searchString.length;
- var lastIndex = subjectString.indexOf(searchString, position);
- return lastIndex !== -1 && lastIndex === position;
- };
- }
- // Calculate width of text from DOM element or string. By Phil Freo <http://philfreo.com>
- $.fn.textWidth = function(text, font) {
- if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').hide().appendTo(document.body);
- $.fn.textWidth.fakeEl.text(text || this.val() || this.text()).css('font', font || this.css('font'));
- return $.fn.textWidth.fakeEl.width();
- };
- /**
- * Base object that all view objects can delegate to.
- * Has the ability to create new objects with itself as the new object's prototype.
- */
- FLExtendableObject = {
- /**
- * Create new object with the current object set as its prototype.
- * @var mixin - Object with properties to be mixed into the final object.
- * @return object
- */
- create: function(mixin) {
- // create a new object with this object as it's prototype.
- var obj = Object.create(this);
- // mix any given properties into it
- obj = $.extend(obj, mixin);
- $(this).trigger('onCreate');
- return obj;
- },
- };
- /**
- * jQuery function to set a class while removing all other classes from
- * the same element that start with the prefix.
- * This is to allow for class states where only one state from the group of classes
- * can be present at any time.
- */
- $.fn.switchClass = function (prefix, ending) {
- return this.each(function() {
- $(this).removeClass(function(i, classesString) {
- var classesToRemove = [];
- var classes = classesString.split(' ');
- for(var i in classes) {
- if (classes[i].startsWith(prefix)) {
- classesToRemove.push(classes[i]);
- }
- }
- return classesToRemove.join(' ');
- });
- return $(this).addClass(prefix + ending);
- });
- };
- var KeyShortcuts = {
- /**
- * Initialize the keyboard shortcut manager.
- * @return void
- */
- init: function() {
- FLBuilder.addHook('cancelTask', this.onCancelTask.bind(this));
- FLBuilder.addHook('showSavedMessage', this.onSaveShortcut.bind(this));
- FLBuilder.addHook('goToNextTab', this.onNextPrevTabShortcut.bind(this, 'next'));
- FLBuilder.addHook('goToPrevTab', this.onNextPrevTabShortcut.bind(this, 'prev'));
- FLBuilder.addHook('endEditingSession', this.onEndEditingSession.bind(this));
- FLBuilder.addHook('restartEditingSession', this.onRestartEditingSession.bind(this));
- this.setDefaultKeyboardShortcuts();
- },
- /**
- * Add single keyboard shortcut
- * @var string A hook to be triggered by `FLBuilder.triggerhook(hook)`
- * @var string The key combination to trigger the command.
- * @var bool isGlobal - If the shortcut should work even inside inputs.
- * @return void
- */
- addShortcut: function( hook, key, isGlobal ) {
- var fn = $.proxy(this, 'onTriggerKey', hook);
- if ( isGlobal ) {
- Mousetrap.bindGlobal(key, fn);
- } else {
- Mousetrap.bind(key, fn);
- }
- },
- /**
- * Clear all registered key commands.
- * @return void
- */
- reset: function() {
- if ( ! FLBuilder.UIIFrame.isEnabled() ) {
- Mousetrap.reset();
- }
- },
- /**
- * Set the default shortcuts
- * @return void
- */
- setDefaultKeyboardShortcuts: function() {
- this.reset();
- for( var action in FLBuilderConfig.keyboardShortcuts ) {
- var code = FLBuilderConfig.keyboardShortcuts[action].keyCode,
- isGlobal = FLBuilderConfig.keyboardShortcuts[action].isGlobal;
- this.addShortcut( action, code, isGlobal);
- }
- },
- /**
- * Handle a key command by triggering the associated hook.
- * @var string the hook to be fired.
- * @return void
- */
- onTriggerKey: function(hook, e) {
- FLBuilder.triggerHook(hook);
- if (e.preventDefault) {
- e.preventDefault();
- } else {
- // internet explorer
- e.returnValue = false;
- }
- },
- /**
- * Cancel out of the current task - triggered by pressing ESC
- * @return void
- */
- onCancelTask: function() {
- // Is the editor in preview mode?
- if (EditingUI.isPreviewing) {
- EditingUI.endPreview();
- return;
- }
- // Are the publish actions showing?
- if (PublishActions.isShowing) {
- PublishActions.hide();
- return;
- }
- // Is the content panel showing?
- if (FLBuilder.ContentPanel.isShowing) {
- FLBuilder.ContentPanel.hide();
- return;
- }
- if ( FLBuilder.UIIFrame.isEnabled() ) {
- FLBuilder.UIIFrame.exitResponsiveEditing();
- return;
- }
- },
- /**
- * Pause the active keyboard shortcut listeners.
- * @return void
- */
- pause: function() {
- Mousetrap.pause();
- },
- /**
- * Unpause the active keyboard shortcut listeners.
- * @return void
- */
- unpause: function() {
- Mousetrap.unpause();
- },
- /**
- * Handle ending the editing session
- * @return void
- */
- onEndEditingSession: function() {
- const actions = FL.Builder.data.getSystemActions()
- actions.setIsEditing( false )
- document.documentElement.classList.remove( 'fl-builder-assistant-visible' )
- this.reset();
- this.addShortcut('restartEditingSession', 'mod+e');
- },
- /**
- * Handle restarting the editing session
- * @return void
- */
- onRestartEditingSession: function() {
- const actions = FL.Builder.data.getSystemActions()
- actions.setIsEditing( true )
- const currentPanel = FL.Builder.data.getSystemState().currentPanel
- if ( 'assistant' === currentPanel ) {
- document.documentElement.classList.add( 'fl-builder-assistant-visible' )
- }
- this.reset();
- this.setDefaultKeyboardShortcuts();
- },
- /**
- * Handle CMD+S Save Shortcut
- *
- * @return void
- */
- onSaveShortcut: function() {
- if (FLBuilder.SaveManager.layoutNeedsPublish()) {
- var message = FLBuilderStrings.savedStatus.hasAlreadySaved;
- FLBuilder.SaveManager.showStatusMessage(message);
- setTimeout(function() {
- FLBuilder.SaveManager.resetStatusMessage();
- }, 2000);
- } else {
- var message = FLBuilderStrings.savedStatus.nothingToSave;
- FLBuilder.SaveManager.showStatusMessage(message);
- setTimeout(function() {
- FLBuilder.SaveManager.resetStatusMessage();
- }, 2000);
- }
- },
- onNextPrevTabShortcut: function( direction, e ) {
- var $lightbox = $('.fl-lightbox:visible', window.parent.document),
- $tabs = $lightbox.find('.fl-builder-settings-tabs a'),
- $activeTab,
- $nextTab;
- if ( $lightbox.length > 0 ) {
- $activeTab = $tabs.filter('a.fl-active');
- if ( 'next' == direction ) {
- if ( $activeTab.is( $tabs.last() ) ) {
- $nextTab = $tabs.first();
- } else {
- $nextTab = $activeTab.next('a');
- }
- } else {
- if ( $activeTab.is( $tabs.first() ) ) {
- $nextTab = $tabs.last();
- } else {
- $nextTab = $activeTab.prev('a');
- }
- }
- $nextTab.trigger('click');
- }
- FLBuilder._calculateSettingsTabsOverflow();
- e.preventDefault();
- },
- };
- /**
- * Publish actions button bar UI
- */
- var PublishActions = FLExtendableObject.create({
- /**
- * Is the button bar showing?
- * @var bool
- */
- isShowing: false,
- /**
- * Setup the bar
- * @return void
- */
- init: function() {
- this.$el = $('.fl-builder-publish-actions', window.parent.document);
- this.$defaultBarButtons = $('.fl-builder-bar-actions', window.parent.document);
- this.$clickAwayMask = $('.fl-builder-publish-actions-click-away-mask', window.parent.document);
- this.$doneBtn = this.$defaultBarButtons.find('.fl-builder-done-button');
- this.$doneBtn.on('click', this.onDoneTriggered.bind(this));
- this.$actions = this.$el.find('.fl-builder-button');
- this.$actions.on('click touchend', this.onActionClicked.bind(this));
- FLBuilder.addHook('triggerDone', this.onDoneTriggered.bind(this));
- var hide = this.hide.bind(this);
- FLBuilder.addHook('cancelPublishActions', hide);
- FLBuilder.addHook('endEditingSession', hide);
- this.$clickAwayMask.on('click', hide );
- },
- /**
- * Fired when the done button is clicked or hook is triggered.
- * @return void
- */
- onDoneTriggered: function() {
- if (FLBuilder.SaveManager.layoutNeedsPublish()) {
- this.show();
- } else {
- if ( FLBuilderConfig.shouldRefreshOnPublish ) {
- FLBuilder._exit();
- } else {
- FLBuilder._exitWithoutRefresh();
- }
- }
- },
- /**
- * Display the publish actions.
- * @return void
- */
- show: function() {
- if (this.isShowing) return;
- // Save existing settings first if any exist. Don't proceed if it fails.
- if ( ! FLBuilder._triggerSettingsSave( false, true ) ) {
- return;
- }
- this.$el.removeClass('is-hidden');
- this.$defaultBarButtons.css('opacity', '0');
- this.$clickAwayMask.show();
- this.isShowing = true;
- FLBuilder.triggerHook('didShowPublishActions');
- },
- /**
- * Hide the publish actions.
- * @return void
- */
- hide: function() {
- if (!this.isShowing) return;
- this.$el.addClass('is-hidden');
- this.$defaultBarButtons.css('opacity', '1');
- this.$clickAwayMask.hide();
- this.isShowing = false;
- },
- /**
- * Fired when a publish action (or cancel) is clicked.
- * @return void
- */
- onActionClicked: function(e) {
- var action = $(e.currentTarget).data('action');
- switch(action) {
- case "dismiss":
- this.hide();
- break;
- case "discard":
- this.hide();
- EditingUI.muteToolbar();
- FLBuilder._discardButtonClicked();
- break;
- case "publish":
- this.hide();
- EditingUI.muteToolbar();
- FLBuilder._publishButtonClicked();
- FLBuilder._destroyOverlayEvents();
- break;
- case "draft":
- this.hide();
- EditingUI.muteToolbar();
- FLBuilder._draftButtonClicked();
- break;
- default:
- // draft
- this.hide();
- EditingUI.muteToolbar();
- FLBuilder._draftButtonClicked();
- }
- FLBuilder.triggerHook( action + 'ButtonClicked' );
- },
- });
- /**
- * Editing UI State Controller
- */
- var EditingUI = {
- /**
- * @var bool - whether or not the editor is in preview mode.
- */
- isPreviewing: false,
- /**
- * Setup the controller.
- * @return void
- */
- init: function() {
- this.$el = $('body', window.parent.document);
- this.$mainToolbar = $('.fl-builder-bar', window.parent.document);
- this.$mainToolbarContent = this.$mainToolbar.find('.fl-builder-bar-content', window.parent.document);
- this.$wpAdminBar = $('#wpadminbar');
- this.$endPreviewBtn = $('.fl-builder--preview-actions .end-preview-btn', window.parent.document);
- FLBuilder.addHook('endEditingSession', this.endEditingSession.bind(this) );
- FLBuilder.addHook('previewLayout', this.togglePreview.bind(this) );
- // End preview btn
- this.$endPreviewBtn.on('click', this.endPreview.bind(this));
- // Preview mode device size icons
- this.$deviceIcons = $('.fl-builder--preview-actions i', window.parent.document);
- this.$deviceIcons.on('click', this.onDeviceIconClick.bind(this));
- // Admin bar link to re-enable editor
- var $link = this.$wpAdminBar.find('#wp-admin-bar-fl-builder-frontend-edit-link > a, #wp-admin-bar-fl-theme-builder-frontend-edit-link > a');
- $link.on('click', this.onClickPageBuilderToolbarLink.bind(this));
- // Take admin bar links out of the tab order
- $('#wpadminbar a').attr('tabindex', '-1');
- var restart = this.restartEditingSession.bind(this);
- FLBuilder.addHook('restartEditingSession', restart);
- FLBuilder.addHook('didHideAllLightboxes', this.unmuteToolbar.bind(this));
- FLBuilder.addHook('didCancelDiscard', this.unmuteToolbar.bind(this));
- FLBuilder.addHook('didEnterRevisionPreview', this.hide.bind(this));
- FLBuilder.addHook('didExitRevisionPreview', this.show.bind(this));
- FLBuilder.addHook('didPublishLayout', this.onPublish.bind(this));
- // FLBuilder.addHook('didPublishLayout', this.onPublishCacheClear.bind(this));
- },
- /**
- * Handle exit w/o preview
- * @return void
- */
- endEditingSession: function() {
- FLBuilder._destroyOverlayEvents();
- FLBuilder._removeAllOverlays();
- FLBuilder._removeEmptyRowAndColHighlights();
- FLBuilder._unbindEvents();
- $('html').add( 'html', window.parent.document ).removeClass('fl-builder-edit').addClass('fl-builder-show-admin-bar');
- $('body').add( 'body', window.parent.document ).removeClass('fl-builder-edit');
- $('#wpadminbar a').attr('tabindex', null );
- $( FLBuilder._contentClass ).removeClass( 'fl-builder-content-editing' );
- this.hideMainToolbar();
- FLBuilder.ContentPanel.hide();
- FLBuilderLayout.init();
- },
- /**
- * Re-enter the editor without refresh after having left without refresh.
- * @return void
- */
- restartEditingSession: function(e) {
- FLBuilder._initTemplateSelector();
- FLBuilder._bindOverlayEvents();
- FLBuilder._highlightEmptyCols();
- FLBuilder._rebindEvents();
- $('html').add( 'html', window.parent.document ).addClass('fl-builder-edit').removeClass('fl-builder-show-admin-bar');
- $('body').add( 'html', window.parent.document ).addClass('fl-builder-edit');
- $('#wpadminbar a').attr('tabindex', '-1');
- $( FLBuilder._contentClass ).addClass( 'fl-builder-content-editing' );
- this.showMainToolbar();
- e.preventDefault();
- },
- /**
- * Handle re-entering the editor when you click the toolbar button.
- * @return void
- */
- onClickPageBuilderToolbarLink: function(e) {
- FLBuilder.triggerHook('restartEditingSession');
- e.preventDefault();
- },
- /**
- * Make admin bar dot green
- *
- * @return void
- */
- onPublish: function() {
- var $dot = this.$wpAdminBar.find('#wp-admin-bar-fl-builder-frontend-edit-link > a span');
- $dot.css('color', '#6bc373');
- },
- /**
- * Reload url via ajax, this rebuilds the cache files.
- */
- onPublishCacheClear: function() {
- FLBuilder.ajax({
- action: 'clear_cache_for_layout',
- }, function(response) {
- console.log(response);
- });
- },
- /**
- * Hides the entire UI.
- * @return void
- */
- hide: function() {
- if ( $( 'html' ).hasClass( 'fl-builder-edit' ) ) {
- FLBuilder._unbindEvents();
- FLBuilder._destroyOverlayEvents();
- FLBuilder._removeAllOverlays();
- $('html').add( 'html', window.parent.document ).removeClass('fl-builder-edit')
- $('body').removeClass('admin-bar');
- this.hideMainToolbar();
- FLBuilder.ContentPanel.hide();
- FLBuilderLayout.init();
- FLBuilder.triggerHook('didHideEditingUI');
- }
- },
- /**
- * Shows the UI when it's hidden.
- * @return void
- */
- show: function() {
- if ( ! $( 'html' ).hasClass( 'fl-builder-edit' ) ) {
- FLBuilder._rebindEvents();
- FLBuilder._bindOverlayEvents();
- this.showMainToolbar();
- FLBuilderResponsiveEditing._switchTo('default');
- $('html').add( 'html', window.parent.document ).addClass('fl-builder-edit');
- $('body').addClass('admin-bar');
- FLBuilder.triggerHook('didShowEditingUI');
- }
- },
- /**
- * Enter Preview Mode
- * @return void
- */
- beginPreview: function() {
- // Save existing settings first if any exist. Don't proceed if it fails.
- if ( ! FLBuilder._triggerSettingsSave( false, true ) ) {
- return;
- }
- this.isPreviewing = true;
- this.hide();
- $('html').add( 'html', window.parent.document ).addClass('fl-builder-preview');
- $('html, body').add( 'html, body', window.parent.document ).removeClass('fl-builder-edit');
- FLBuilder._removeEmptyRowAndColHighlights();
- FLBuilder.triggerHook('didBeginPreview');
- FLBuilderResponsivePreview.enter();
- },
- /**
- * Leave preview module
- * @return void
- */
- endPreview: function() {
- this.isPreviewing = false;
- this.show();
- FLBuilder._highlightEmptyCols();
- FLBuilderResponsivePreview.exit();
- $('html').add( 'html', window.parent.document ).removeClass('fl-builder-preview');
- $('html, body').add( 'html, body', window.parent.document ).addClass('fl-builder-edit');
- },
- /**
- * Toggle in and out of preview mode
- * @return void
- */
- togglePreview: function() {
- if (this.isPreviewing) {
- this.endPreview();
- } else {
- this.beginPreview();
- }
- },
- /**
- * Hide the editor toolbar
- * @return void
- */
- hideMainToolbar: function() {
- this.$mainToolbar.addClass('is-hidden');
- $( 'html', window.parent.document ).removeClass('fl-builder-is-showing-toolbar');
- },
- /**
- * Show the editor toolbar
- * @return void
- */
- showMainToolbar: function() {
- this.unmuteToolbar();
- this.$mainToolbar.removeClass('is-hidden');
- $( 'html', window.parent.document ).addClass('fl-builder-is-showing-toolbar');
- },
- /**
- * Handle clicking a responsive device icon while in preview
- * @return void
- */
- onDeviceIconClick: function(e) {
- var mode = $(e.target).data('mode');
- FLBuilderResponsivePreview.switchTo(mode);
- FLBuilderResponsivePreview._showSize(mode);
- },
- /**
- * Make toolbar innert
- * @return void
- */
- muteToolbar: function() {
- this.$mainToolbarContent.addClass('is-muted');
- FLBuilder._hideTipTips();
- },
- /**
- * Re-activate the toolbar
- * @return void
- */
- unmuteToolbar: function() {
- this.$mainToolbarContent.removeClass('is-muted');
- },
- };
- /**
- * Browser history logic.
- */
- var BrowserState = {
- isEditing: true,
- /**
- * Init the browser state controller
- *
- * @return void
- */
- init: function() {
- if ( history.pushState ) {
- FLBuilder.addHook('endEditingSession', this.onLeaveBuilder.bind(this) );
- FLBuilder.addHook('restartEditingSession', this.onEnterBuilder.bind(this) );
- }
- },
- /**
- * Handle restarting the edit session.
- *
- * @return void
- */
- onEnterBuilder: function() {
- history.replaceState( {}, document.title, FLBuilderConfig.editUrl );
- const actions = FL.Builder.data.getSystemActions()
- actions.setIsEditing( true )
- this.isEditing = true;
- },
- /**
- * Handle exiting the builder.
- *
- * @return void
- */
- onLeaveBuilder: function() {
- history.replaceState( {}, document.title, FLBuilderConfig.url );
- const actions = FL.Builder.data.getSystemActions()
- actions.setIsEditing( false )
- this.isEditing = false;
- },
- };
- /**
- * Content Library Search
- */
- var SearchUI = {
- /**
- * Setup the search controller
- * @return void
- */
- init: function() {
- this.$searchBox = $('.fl-builder--search', window.parent.document);
- this.$searchBoxInput = this.$searchBox.find('input#fl-builder-search-input');
- this.$searchBoxClear = this.$searchBox.find('.search-clear');
- this.$searchBoxInput.on('focus', this.onSearchInputFocus.bind(this));
- this.$searchBoxInput.on('blur', this.onSearchInputBlur.bind(this));
- this.$searchBoxInput.on('keyup', this.onSearchTermChange.bind(this));
- this.$searchBoxClear.on('click', this.onSearchTermClearClicked.bind(this));
- this.renderSearchResults = wp.template('fl-search-results-panel');
- this.renderNoResults = wp.template('fl-search-no-results');
- FLBuilder.addHook('didStartDrag', this.hideSearchResults.bind(this));
- FLBuilder.addHook('focusSearch', this.focusSearchBox.bind(this));
- },
- focusSearchBox: function() {
- this.$searchBoxInput.trigger('focus');
- },
- /**
- * Fires when focusing on the search field.
- * @return void
- */
- onSearchInputFocus: function() {
- this.$searchBox.addClass('is-expanded');
- FLBuilder.triggerHook('didFocusSearchBox');
- },
- /**
- * Fires when blurring out of the search field.
- * @return void
- */
- onSearchInputBlur: function(e) {
- this.$searchBox.removeClass('is-expanded has-text');
- this.$searchBoxInput.val('');
- this.hideSearchResults();
- },
- /**
- * Fires when a key is pressed inside the search field.
- * @return void
- */
- onSearchTermChange: function(e) {
- if (e.key == 'Escape') {
- this.$searchBoxInput.blur();
- return;
- }
- FLBuilder.triggerHook('didBeginSearch');
- var value = this.$searchBoxInput.val();
- if (value != '') {
- this.$searchBox.addClass('has-text');
- } else {
- this.$searchBox.removeClass('has-text');
- }
- var results = FLBuilder.Search.byTerm(value);
- if (results.term != "") {
- this.showSearchResults(results);
- } else {
- this.hideSearchResults();
- }
- },
- /**
- * Fires when the clear button is clicked.
- * @return void
- */
- onSearchTermClearClicked: function() {
- this.$searchBox.removeClass('has-text').addClass('is-expanded');
- this.$searchBoxInput.val('').focus();
- this.hideSearchResults();
- },
- /**
- * Display the found results in the results panel.
- * @var Object - the found results
- * @return void
- */
- showSearchResults: function(data) {
- if (data.total > 0) {
- var $html = $(this.renderSearchResults(data)),
- $panel = $('.fl-builder--search-results-panel', window.parent.document);
- $panel.html($html);
- FLBuilder._initSortables();
- } else {
- var $html = $(this.renderNoResults(data)),
- $panel = $('.fl-builder--search-results-panel', window.parent.document);
- $panel.html($html);
- }
- $('body', window.parent.document).addClass('fl-builder-search-results-panel-is-showing');
- },
- /**
- * Hide the search results panel
- * @return void
- */
- hideSearchResults: function() {
- $('body', window.parent.document).removeClass('fl-builder-search-results-panel-is-showing');
- },
- };
- var RowResize = {
- /**
- * @var {jQuery}
- */
- $row: null,
- /**
- * @var {jQuery}
- */
- $rowContent: null,
- /**
- * @var {Object}
- */
- row: null,
- /**
- * @var {Object}
- */
- drag: {},
- /**
- * Setup basic events for row content overlays
- * @return void
- */
- init: function() {
- if ( this.userCanResize() ) {
- var $layoutContent = $( FLBuilder._contentClass );
- $layoutContent.on( 'mouseenter touchstart', '.fl-row, .fl-block-overlay', this.onDragHandleHover.bind(this) );
- $layoutContent.on( 'mousedown touchstart', '.fl-block-row-resize', this.onDragHandleDown.bind(this) );
- }
- },
- /**
- * Check if the user is able to resize rows
- *
- * @return bool
- */
- userCanResize: function() {
- return FLBuilderConfig.rowResize.userCanResizeRows;
- },
- /**
- * Hover over a row resize drag handle.
- * @return void
- */
- onDragHandleHover: function(e) {
- if (this.drag.isDragging) {
- return
- };
- var $this = this,
- originalWidth,
- $handle = $(e.target),
- row = $handle.closest('.fl-row'),
- node = row.data('node'),
- form = $( '.fl-builder-row-settings[data-node=' + node + ']', window.parent.document ),
- unitField = form.find( '[name=max_content_width_unit]' ),
- unit = 'px';
- $this.onSettingsReady(node, function(settings){
- // Get unit.
- if (unitField.length) {
- unit = unitField.val();
- } else if ('undefined' !== typeof settings) {
- unit = settings.max_content_width_unit;
- }
- $this.$row = row;
- $this.$rowContent = $this.$row.find('.fl-row-content');
- $this.row = {
- node: node,
- form: form,
- unit: unit,
- isFixedWidth: $this.$row.hasClass('fl-row-fixed-width'),
- parentWidth: 'vw' === unit ? $( window ).width() : $this.$row.parent().width(),
- };
- $this.drag = {
- edge: null,
- isDragging: false,
- originalPosition: null,
- originalWidth: null,
- calculatedWidth: null,
- operation: null,
- };
- if ($this.row.isFixedWidth) {
- $this.drag.originalWidth = $this.$row.width();
- } else {
- $this.drag.originalWidth = $this.$rowContent.width();
- }
- $this.dragInit();
- });
- },
- /**
- * Check if FLBuilderSettingsConfig.node is available.
- * @return void
- */
- onSettingsReady: function(nodeId, callback) {
- var nodes = 'undefined' !== typeof FLBuilderSettingsConfig.nodes ? FLBuilderSettingsConfig.nodes : null;
- if (null !== nodes && 'undefined' !== typeof nodes[ nodeId ] ) {
- callback( nodes[ nodeId ] );
- if (null != RowResize._mouseEnterTimeout) {
- clearTimeout( RowResize._mouseEnterTimeout );
- RowResize._mouseEnterTimeout = null;
- }
- } else {
- // If settings is not yet available, check again by timeout.
- clearTimeout( RowResize._mouseEnterTimeout );
- RowResize._mouseEnterTimeout = setTimeout(this.onSettingsReady.bind(this), 350, nodeId, callback);
- }
- },
- /**
- * Handle mouse down on the drag handle
- * @return void
- */
- onDragHandleDown: function() {
- $('body').add( 'body', window.parent.document ).addClass( 'fl-builder-row-resizing' );
- if (null != RowResize._mouseEnterTimeout) {
- clearTimeout( RowResize._mouseEnterTimeout );
- RowResize._mouseEnterTimeout = null;
- }
- },
- /**
- * Setup the draggable handler
- * @return void
- */
- dragInit: function(e) {
- this.$row.find('.fl-block-row-resize').draggable( {
- axis : 'x',
- start : this.dragStart.bind(this),
- drag : this.dragging.bind(this),
- stop : this.dragStop.bind(this)
- });
- },
- /**
- * Handle drag started
- * @var {Event}
- * @var {Object}
- * @return void
- */
- dragStart: function(e, ui) {
- var body = $( 'body' ).add( 'body', window.parent.document ),
- $handle = $(ui.helper);
- this.drag.isDragging = true;
- if (this.row.isFixedWidth) {
- this.drag.originalWidth = this.$row.width();
- } else {
- this.drag.originalWidth = this.$rowContent.width();
- }
- if ($handle.hasClass( 'fl-block-col-resize-e' )) {
- this.drag.edge = 'e';
- this.$feedback = $handle.find('.fl-block-col-resize-feedback-left');
- }
- if ($handle.hasClass( 'fl-block-col-resize-w' )) {
- this.drag.edge = 'w';
- this.$feedback = $handle.find('.fl-block-col-resize-feedback-right');
- }
- body.addClass( 'fl-builder-row-resizing' );
- FLBuilder._colResizing = true;
- FLBuilder._destroyOverlayEvents();
- FLBuilder._closePanel();
- },
- /**
- * Handle drag
- * @var {Event}
- * @var {Object}
- * @return void
- */
- dragging: function(e, ui) {
- var currentPosition = ui.position.left,
- originalPosition = ui.originalPosition.left,
- originalWidth = this.drag.originalWidth,
- distance = 0,
- edge = this.drag.edge,
- minAllowedWidth = FLBuilderConfig.rowResize.minAllowedWidth,
- maxAllowedWidth = FLBuilderConfig.rowResize.maxAllowedWidth;
- if ( FLBuilderConfig.isRtl ) {
- edge = ( 'w' == edge ) ? 'e' : 'w'; // Flip the direction
- }
- if (originalPosition > currentPosition) {
- if (edge === 'w') {
- this.drag.operation = '+';
- } else {
- this.drag.operation = '-';
- }
- } else {
- if (edge === 'e') {
- this.drag.operation = '+';
- } else {
- this.drag.operation = '-';
- }
- }
- distance = Math.abs(originalPosition - currentPosition);
- if (this.drag.operation === '+') {
- this.drag.calculatedWidth = originalWidth + (distance * 2);
- } else {
- this.drag.calculatedWidth = originalWidth - (distance * 2);
- }
- if ( false !== minAllowedWidth && this.drag.calculatedWidth < minAllowedWidth ) {
- this.drag.calculatedWidth = minAllowedWidth;
- }
- if ( false !== maxAllowedWidth && this.drag.calculatedWidth > maxAllowedWidth ) {
- this.drag.calculatedWidth = maxAllowedWidth;
- }
- if (this.row.isFixedWidth) {
- this.$row.css('max-width', this.drag.calculatedWidth + 'px');
- }
- this.$rowContent.css('max-width', this.drag.calculatedWidth + 'px');
- if ( 'px' !== this.row.unit ) {
- this.drag.calculatedWidth = Math.round( this.drag.calculatedWidth / this.row.parentWidth * 100 );
- }
- if (!_.isUndefined(this.$feedback)) {
- this.$feedback.html(this.drag.calculatedWidth + this.row.unit).show();
- }
- if ( this.row.form.length ) {
- this.row.form.find( '[name=max_content_width]' ).val( this.drag.calculatedWidth );
- }
- // Dispatch update to store
- requestAnimationFrame( () => {
- const actions = FL.Builder.data.getLayoutActions()
- actions.resizeRowContent( this.row.node, this.drag.calculatedWidth, false )
- } )
- },
- /**
- * Handle drag ended
- * @var {Event}
- * @var {Object}
- * @return void
- */
- dragStop: function(e, ui) {
- this.drag.isDragging = false;
- if (!_.isUndefined(this.$feedback)) {
- this.$feedback.hide();
- }
- // Dispatch update to store
- const actions = FL.Builder.data.getLayoutActions()
- actions.resizeRowContent( this.row.node, this.drag.calculatedWidth )
- FLBuilder._bindOverlayEvents();
- $( 'body' ).add( 'body', window.parent.document ).removeClass( 'fl-builder-row-resizing' );
- requestAnimationFrame( () => {
- $( '.fl-block-overlay' ).each( function() {
- FLBuilder._buildOverlayOverflowMenu( $( this ) );
- } );
- } )
- // Set the resizing flag to false with a timeout so other events get the right value.
- setTimeout( function() { FLBuilder._colResizing = false; }, 50 );
- FLBuilder.triggerHook( 'didResizeRow', {
- rowId : this.row.node,
- rowWidth : this.drag.calculatedWidth
- } );
- },
- };
- var Toolbar = {
- /**
- * wp.template id suffix
- */
- templateName: 'fl-toolbar',
- /**
- * Initialize the toolbar controller
- *
- * @return void
- */
- init: function() {
- this.template = wp.template(this.templateName);
- this.render();
- this.initTipTips();
- /* "Add Content" Button */
- var $addContentBtn = this.$el.find('.fl-builder-content-panel-button');
- $addContentBtn.on('click', FLBuilder._togglePanel );
- this.$el.find('.fl-builder-buy-button').on('click', FLBuilder._upgradeClicked);
- this.$el.find('.fl-builder-upgrade-button').on('click', FLBuilder._upgradeClicked);
- this.$el.find('#fl-builder-toggle-notifications').on('click', this.onNotificationsButtonClicked.bind(this) );
- FLBuilder.addHook('notificationsLoaded', this.onNotificationsLoaded.bind(this));
- },
- /**
- * Render the toolbar html
- * @param object
- * @return void
- */
- render: function(data) {
- var $html = $(this.template(data));
- this.$el = $html;
- this.el = $html.get(0);
- EditingUI.$mainToolbar = this.$el;
- $( 'html', window.parent.document ).addClass( 'fl-builder-is-showing-toolbar' );
- $( 'body', window.parent.document ).prepend( $html );
- },
- /**
- * Add tooltips
- *
- * @return void
- */
- initTipTips: function() {
- // Publish actions tooltip
- $('.fl-builder-publish-actions .fl-builder-button-group .fl-builder-button', window.parent.document).tipTip({
- defaultPosition: 'bottom',
- edgeOffset: 6
- });
- },
- onNotificationsButtonClicked: function() {
- FLBuilder.triggerHook('toggleNotifications');
- },
- onNotificationsLoaded: function() {
- $('body').add( 'body', window.parent.document ).removeClass('fl-builder-has-new-notifications');
- var data = {
- action: 'fl_builder_notifications',
- read: true,
- }
- FLBuilder.ajax(data);
- }
- };
- /**
- * Kick off initializers when FLBuilder inits.
- */
- $(function() {
- // Render Order matters here
- FLBuilder.ContentPanel.init();
- if ( !FLBuilderConfig.simpleUi ) {
- FLBuilder.MainMenu.init();
- }
- if ( FLBuilderConfig.showToolbar ) {
- Toolbar.init();
- FLBuilder.ContentPanel.alignPanelArrow();
- } else {
- $('html').add( 'html', window.parent.document ).addClass('fl-builder-no-toolbar');
- }
- // End Render Order
- KeyShortcuts.init();
- EditingUI.init();
- BrowserState.init();
- RowResize.init();
- PublishActions.init();
- FLBuilder.triggerHook( 'didInitUI' );
- });
- })(jQuery, FLBuilder);
|