Version Description
- 2 April 2019 =
- Layout builder widget: Call styles sanitization in update.
- Live editor: Only call
process_raw_widgets
once for preview data. - Add a setting for whether to display SiteOrigin Page Builder post state.
- Sidebars emulator: Cache the result of url_to_postid().
- Prevent affecting child layouts with parent layouts' CSS.
Download this release
Release Info
Developer | gpriday |
Plugin | ![]() |
Version | 2.10.3 |
Comparing to | |
See all releases |
Code changes from version 2.10.2 to 2.10.3
- compat/js/siteorigin-panels-layout-block.js +351 -351
- inc/admin.php +3 -1
- inc/css-builder.php +1 -1
- inc/live-editor.php +0 -35
- inc/renderer.php +17 -4
- inc/settings.php +11 -0
- inc/widgets/layout.php +11 -7
- js/siteorigin-panels-2101.js +0 -7438
- js/siteorigin-panels-2101.min.js +0 -1
- js/{siteorigin-panels-2102.js → siteorigin-panels-2103.js} +0 -0
- js/{siteorigin-panels-2102.min.js → siteorigin-panels-2103.min.js} +0 -0
- js/styling-2101.js +0 -62
- js/styling-2101.min.js +0 -1
- js/{styling-2102.js → styling-2103.js} +0 -0
- js/{styling-2102.min.js → styling-2103.min.js} +0 -0
- lang/siteorigin-panels.pot +158 -150
- readme.txt +9 -2
- siteorigin-panels.php +3 -3
compat/js/siteorigin-panels-layout-block.js
CHANGED
@@ -1,352 +1,352 @@
|
|
1 |
-
"use strict";
|
2 |
-
|
3 |
-
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
4 |
-
|
5 |
-
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
6 |
-
|
7 |
-
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
8 |
-
|
9 |
-
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
10 |
-
|
11 |
-
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
|
12 |
-
|
13 |
-
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
14 |
-
|
15 |
-
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
16 |
-
|
17 |
-
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
18 |
-
|
19 |
-
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
20 |
-
|
21 |
-
var _lodash = lodash,
|
22 |
-
isEqual = _lodash.isEqual,
|
23 |
-
debounce = _lodash.debounce,
|
24 |
-
isEmpty = _lodash.isEmpty,
|
25 |
-
isFunction = _lodash.isFunction;
|
26 |
-
var registerBlockType = wp.blocks.registerBlockType;
|
27 |
-
var _wp$element = wp.element,
|
28 |
-
Component = _wp$element.Component,
|
29 |
-
Fragment = _wp$element.Fragment,
|
30 |
-
RawHTML = _wp$element.RawHTML,
|
31 |
-
createRef = _wp$element.createRef;
|
32 |
-
var BlockControls = wp.editor.BlockControls;
|
33 |
-
var _wp$components = wp.components,
|
34 |
-
Toolbar = _wp$components.Toolbar,
|
35 |
-
IconButton = _wp$components.IconButton,
|
36 |
-
Spinner = _wp$components.Spinner;
|
37 |
-
var __ = wp.i18n.__;
|
38 |
-
var _window = window,
|
39 |
-
soPanelsBlockEditorAdmin = _window.soPanelsBlockEditorAdmin;
|
40 |
-
|
41 |
-
var SiteOriginPanelsLayoutBlock =
|
42 |
-
/*#__PURE__*/
|
43 |
-
function (_Component) {
|
44 |
-
_inherits(SiteOriginPanelsLayoutBlock, _Component);
|
45 |
-
|
46 |
-
function SiteOriginPanelsLayoutBlock(props) {
|
47 |
-
var _this;
|
48 |
-
|
49 |
-
_classCallCheck(this, SiteOriginPanelsLayoutBlock);
|
50 |
-
|
51 |
-
_this = _possibleConstructorReturn(this, _getPrototypeOf(SiteOriginPanelsLayoutBlock).call(this, props));
|
52 |
-
var editMode = soPanelsBlockEditorAdmin.defaultMode === 'edit' || isEmpty(props.panelsData);
|
53 |
-
_this.state = {
|
54 |
-
editing: editMode,
|
55 |
-
loadingPreview: !editMode,
|
56 |
-
previewHtml: ''
|
57 |
-
};
|
58 |
-
_this.panelsContainer = createRef();
|
59 |
-
_this.previewContainer = createRef();
|
60 |
-
_this.panelsInitialized = false;
|
61 |
-
_this.previewInitialized = false;
|
62 |
-
return _this;
|
63 |
-
}
|
64 |
-
|
65 |
-
_createClass(SiteOriginPanelsLayoutBlock, [{
|
66 |
-
key: "componentDidMount",
|
67 |
-
value: function componentDidMount() {
|
68 |
-
this.isStillMounted = true;
|
69 |
-
|
70 |
-
if (this.state.editing) {
|
71 |
-
this.setupPanels();
|
72 |
-
} else if (!this.state.editing && !this.previewInitialized) {
|
73 |
-
this.fetchPreview(this.props);
|
74 |
-
this.fetchPreview = debounce(this.fetchPreview, 500);
|
75 |
-
}
|
76 |
-
}
|
77 |
-
}, {
|
78 |
-
key: "componentWillUnmount",
|
79 |
-
value: function componentWillUnmount() {
|
80 |
-
this.isStillMounted = false;
|
81 |
-
|
82 |
-
if (this.builderView) {
|
83 |
-
this.builderView.off('content_change');
|
84 |
-
}
|
85 |
-
}
|
86 |
-
}, {
|
87 |
-
key: "componentDidUpdate",
|
88 |
-
value: function componentDidUpdate(prevProps) {
|
89 |
-
// let propsChanged = !isEqual( prevProps.panelsData, this.props.panelsData );
|
90 |
-
if (this.state.editing && !this.panelsInitialized) {
|
91 |
-
this.setupPanels();
|
92 |
-
} else if (this.state.loadingPreview) {
|
93 |
-
this.fetchPreview(this.props);
|
94 |
-
} else if (!this.previewInitialized && this.previewContainer.current) {
|
95 |
-
$(document).trigger('panels_setup_preview');
|
96 |
-
this.previewInitialized = true;
|
97 |
-
}
|
98 |
-
}
|
99 |
-
}, {
|
100 |
-
key: "setupPanels",
|
101 |
-
value: function setupPanels() {
|
102 |
-
var _this2 = this;
|
103 |
-
|
104 |
-
var $panelsContainer = jQuery(this.panelsContainer.current);
|
105 |
-
var config = {
|
106 |
-
editorType: 'standalone'
|
107 |
-
};
|
108 |
-
var builderModel = new panels.model.builder();
|
109 |
-
this.builderView = new panels.view.builder({
|
110 |
-
model: builderModel,
|
111 |
-
config: config
|
112 |
-
}); // Make sure panelsData is defined and clone so that we don't alter the underlying attribute.
|
113 |
-
|
114 |
-
var panelsData = JSON.parse(JSON.stringify($.extend({}, this.props.panelsData))); // Disable block selection while dragging rows or widgets.
|
115 |
-
|
116 |
-
var rowOrWidgetMouseDown = function rowOrWidgetMouseDown() {
|
117 |
-
if (isFunction(_this2.props.onRowOrWidgetMouseDown)) {
|
118 |
-
_this2.props.onRowOrWidgetMouseDown();
|
119 |
-
}
|
120 |
-
|
121 |
-
var rowOrWidgetMouseUp = function rowOrWidgetMouseUp() {
|
122 |
-
$(document).off('mouseup', rowOrWidgetMouseUp);
|
123 |
-
|
124 |
-
if (isFunction(_this2.props.onRowOrWidgetMouseUp)) {
|
125 |
-
_this2.props.onRowOrWidgetMouseUp();
|
126 |
-
}
|
127 |
-
};
|
128 |
-
|
129 |
-
$(document).on('mouseup', rowOrWidgetMouseUp);
|
130 |
-
};
|
131 |
-
|
132 |
-
this.builderView.on('row_added', function () {
|
133 |
-
_this2.builderView.$('.so-row-move').off('mousedown', rowOrWidgetMouseDown);
|
134 |
-
|
135 |
-
_this2.builderView.$('.so-row-move').on('mousedown', rowOrWidgetMouseDown);
|
136 |
-
|
137 |
-
_this2.builderView.$('.so-widget').off('mousedown', rowOrWidgetMouseDown);
|
138 |
-
|
139 |
-
_this2.builderView.$('.so-widget').on('mousedown', rowOrWidgetMouseDown);
|
140 |
-
});
|
141 |
-
this.builderView.on('widget_added', function () {
|
142 |
-
_this2.builderView.$('.so-widget').off('mousedown', rowOrWidgetMouseDown);
|
143 |
-
|
144 |
-
_this2.builderView.$('.so-widget').on('mousedown', rowOrWidgetMouseDown);
|
145 |
-
});
|
146 |
-
this.builderView.render().attach({
|
147 |
-
container: $panelsContainer
|
148 |
-
}).setData(panelsData);
|
149 |
-
this.builderView.trigger('builder_resize');
|
150 |
-
this.builderView.on('content_change', function () {
|
151 |
-
var newPanelsData = _this2.builderView.getData();
|
152 |
-
|
153 |
-
_this2.panelsDataChanged = !isEqual(panelsData, newPanelsData);
|
154 |
-
|
155 |
-
if (_this2.panelsDataChanged) {
|
156 |
-
if (_this2.props.onContentChange && isFunction(_this2.props.onContentChange)) {
|
157 |
-
_this2.props.onContentChange(newPanelsData);
|
158 |
-
}
|
159 |
-
|
160 |
-
_this2.setState({
|
161 |
-
loadingPreview: true,
|
162 |
-
previewHtml: ''
|
163 |
-
});
|
164 |
-
}
|
165 |
-
});
|
166 |
-
$(document).trigger('panels_setup', this.builderView);
|
167 |
-
this.panelsInitialized = true;
|
168 |
-
}
|
169 |
-
}, {
|
170 |
-
key: "fetchPreview",
|
171 |
-
value: function fetchPreview(props) {
|
172 |
-
var _this3 = this;
|
173 |
-
|
174 |
-
if (!this.isStillMounted) {
|
175 |
-
return;
|
176 |
-
}
|
177 |
-
|
178 |
-
this.previewInitialized = false;
|
179 |
-
var fetchRequest = this.currentFetchRequest = $.post({
|
180 |
-
url: soPanelsBlockEditorAdmin.previewUrl,
|
181 |
-
data: {
|
182 |
-
action: 'so_panels_layout_block_preview',
|
183 |
-
panelsData: JSON.stringify(props.panelsData)
|
184 |
-
}
|
185 |
-
}).then(function (preview) {
|
186 |
-
if (_this3.isStillMounted && fetchRequest === _this3.currentFetchRequest && preview) {
|
187 |
-
_this3.setState({
|
188 |
-
previewHtml: preview,
|
189 |
-
loadingPreview: false
|
190 |
-
});
|
191 |
-
}
|
192 |
-
});
|
193 |
-
return fetchRequest;
|
194 |
-
}
|
195 |
-
}, {
|
196 |
-
key: "render",
|
197 |
-
value: function render() {
|
198 |
-
var _this4 = this;
|
199 |
-
|
200 |
-
var panelsData = this.props.panelsData;
|
201 |
-
|
202 |
-
var switchToEditing = function switchToEditing() {
|
203 |
-
_this4.panelsInitialized = false;
|
204 |
-
|
205 |
-
_this4.setState({
|
206 |
-
editing: true
|
207 |
-
});
|
208 |
-
};
|
209 |
-
|
210 |
-
var switchToPreview = function switchToPreview() {
|
211 |
-
if (panelsData) {
|
212 |
-
_this4.setState({
|
213 |
-
editing: false
|
214 |
-
});
|
215 |
-
}
|
216 |
-
};
|
217 |
-
|
218 |
-
if (this.state.editing) {
|
219 |
-
return React.createElement(Fragment, null, React.createElement(BlockControls, null, React.createElement(Toolbar, null, React.createElement(IconButton, {
|
220 |
-
icon: "visibility",
|
221 |
-
className: "components-icon-button components-toolbar__control",
|
222 |
-
label: __('Preview layout.', 'siteorigin-panels'),
|
223 |
-
onClick: switchToPreview
|
224 |
-
}))), React.createElement("div", {
|
225 |
-
key: "layout-block",
|
226 |
-
className: "siteorigin-panels-layout-block-container",
|
227 |
-
ref: this.panelsContainer
|
228 |
-
}));
|
229 |
-
} else {
|
230 |
-
var loadingPreview = this.state.loadingPreview;
|
231 |
-
return React.createElement(Fragment, null, React.createElement(BlockControls, null, React.createElement(Toolbar, null, React.createElement(IconButton, {
|
232 |
-
icon: "edit",
|
233 |
-
className: "components-icon-button components-toolbar__control",
|
234 |
-
label: __('Edit layout.', 'siteorigin-panels'),
|
235 |
-
onClick: switchToEditing
|
236 |
-
}))), React.createElement("div", {
|
237 |
-
key: "preview",
|
238 |
-
className: "so-panels-block-layout-preview-container"
|
239 |
-
}, loadingPreview ? React.createElement("div", {
|
240 |
-
className: "so-panels-spinner-container"
|
241 |
-
}, React.createElement("span", null, React.createElement(Spinner, null))) : React.createElement("div", {
|
242 |
-
className: "so-panels-raw-html-container",
|
243 |
-
ref: this.previewContainer
|
244 |
-
}, React.createElement(RawHTML, null, this.state.previewHtml))));
|
245 |
-
}
|
246 |
-
}
|
247 |
-
}]);
|
248 |
-
|
249 |
-
return SiteOriginPanelsLayoutBlock;
|
250 |
-
}(Component);
|
251 |
-
|
252 |
-
registerBlockType('siteorigin-panels/layout-block', {
|
253 |
-
title: __('SiteOrigin Layout', 'siteorigin-panels'),
|
254 |
-
description: __("Build a layout using SiteOrigin's Page Builder.", 'siteorigin-panels'),
|
255 |
-
icon: function icon() {
|
256 |
-
return React.createElement("span", {
|
257 |
-
className: "siteorigin-panels-block-icon"
|
258 |
-
});
|
259 |
-
},
|
260 |
-
category: 'layout',
|
261 |
-
keywords: ['page builder', 'column,grid', 'panel'],
|
262 |
-
supports: {
|
263 |
-
html: false
|
264 |
-
},
|
265 |
-
attributes: {
|
266 |
-
panelsData: {
|
267 |
-
type: 'object'
|
268 |
-
}
|
269 |
-
},
|
270 |
-
edit: function edit(_ref) {
|
271 |
-
var attributes = _ref.attributes,
|
272 |
-
setAttributes = _ref.setAttributes,
|
273 |
-
toggleSelection = _ref.toggleSelection;
|
274 |
-
|
275 |
-
var onLayoutBlockContentChange = function onLayoutBlockContentChange(newPanelsData) {
|
276 |
-
if (!_.isEmpty(newPanelsData.widgets)) {
|
277 |
-
// Send
|
278 |
-
$.post(soPanelsBlockEditorAdmin.sanitizeUrl, {
|
279 |
-
action: 'so_panels_layout_block_sanitize',
|
280 |
-
panelsData: JSON.stringify(newPanelsData)
|
281 |
-
}, function (sanitizedPanelsData) {
|
282 |
-
if (sanitizedPanelsData !== '') {
|
283 |
-
setAttributes({
|
284 |
-
panelsData: sanitizedPanelsData
|
285 |
-
});
|
286 |
-
}
|
287 |
-
});
|
288 |
-
}
|
289 |
-
};
|
290 |
-
|
291 |
-
var disableSelection = function disableSelection() {
|
292 |
-
toggleSelection(false);
|
293 |
-
};
|
294 |
-
|
295 |
-
var enableSelection = function enableSelection() {
|
296 |
-
toggleSelection(true);
|
297 |
-
};
|
298 |
-
|
299 |
-
return React.createElement(SiteOriginPanelsLayoutBlock, {
|
300 |
-
panelsData: attributes.panelsData,
|
301 |
-
onContentChange: onLayoutBlockContentChange,
|
302 |
-
onRowOrWidgetMouseDown: disableSelection,
|
303 |
-
onRowOrWidgetMouseUp: enableSelection
|
304 |
-
});
|
305 |
-
},
|
306 |
-
save: function save() {
|
307 |
-
// Render in PHP
|
308 |
-
return null;
|
309 |
-
}
|
310 |
-
});
|
311 |
-
|
312 |
-
(function ($) {
|
313 |
-
if (soPanelsBlockEditorAdmin.showAddButton) {
|
314 |
-
$(function () {
|
315 |
-
setTimeout(function () {
|
316 |
-
var editorDispatch = wp.data.dispatch('core/editor');
|
317 |
-
var editorSelect = wp.data.select('core/editor');
|
318 |
-
var tmpl = $('#siteorigin-panels-add-layout-block-button').html();
|
319 |
-
var $addButton = $(tmpl).insertAfter('.editor-writing-flow > div:first');
|
320 |
-
$addButton.on('click', function () {
|
321 |
-
var layoutBlock = wp.blocks.createBlock('siteorigin-panels/layout-block', {});
|
322 |
-
var isEmpty = editorSelect.isEditedPostEmpty();
|
323 |
-
|
324 |
-
if (isEmpty) {
|
325 |
-
var blocks = editorSelect.getBlocks();
|
326 |
-
|
327 |
-
if (blocks.length) {
|
328 |
-
editorDispatch.replaceBlock(blocks[0].clientId, layoutBlock);
|
329 |
-
} else {
|
330 |
-
editorDispatch.insertBlock(layoutBlock);
|
331 |
-
}
|
332 |
-
} else {
|
333 |
-
editorDispatch.insertBlock(layoutBlock);
|
334 |
-
}
|
335 |
-
});
|
336 |
-
|
337 |
-
var hideButtonIfBlocks = function hideButtonIfBlocks() {
|
338 |
-
var isEmpty = wp.data.select('core/editor').isEditedPostEmpty();
|
339 |
-
|
340 |
-
if (isEmpty) {
|
341 |
-
$addButton.show();
|
342 |
-
} else {
|
343 |
-
$addButton.hide();
|
344 |
-
}
|
345 |
-
};
|
346 |
-
|
347 |
-
wp.data.subscribe(hideButtonIfBlocks);
|
348 |
-
hideButtonIfBlocks();
|
349 |
-
}, 100);
|
350 |
-
});
|
351 |
-
}
|
352 |
})(jQuery);
|
1 |
+
"use strict";
|
2 |
+
|
3 |
+
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
4 |
+
|
5 |
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
6 |
+
|
7 |
+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
8 |
+
|
9 |
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
10 |
+
|
11 |
+
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
|
12 |
+
|
13 |
+
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
14 |
+
|
15 |
+
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
16 |
+
|
17 |
+
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
18 |
+
|
19 |
+
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
20 |
+
|
21 |
+
var _lodash = lodash,
|
22 |
+
isEqual = _lodash.isEqual,
|
23 |
+
debounce = _lodash.debounce,
|
24 |
+
isEmpty = _lodash.isEmpty,
|
25 |
+
isFunction = _lodash.isFunction;
|
26 |
+
var registerBlockType = wp.blocks.registerBlockType;
|
27 |
+
var _wp$element = wp.element,
|
28 |
+
Component = _wp$element.Component,
|
29 |
+
Fragment = _wp$element.Fragment,
|
30 |
+
RawHTML = _wp$element.RawHTML,
|
31 |
+
createRef = _wp$element.createRef;
|
32 |
+
var BlockControls = wp.editor.BlockControls;
|
33 |
+
var _wp$components = wp.components,
|
34 |
+
Toolbar = _wp$components.Toolbar,
|
35 |
+
IconButton = _wp$components.IconButton,
|
36 |
+
Spinner = _wp$components.Spinner;
|
37 |
+
var __ = wp.i18n.__;
|
38 |
+
var _window = window,
|
39 |
+
soPanelsBlockEditorAdmin = _window.soPanelsBlockEditorAdmin;
|
40 |
+
|
41 |
+
var SiteOriginPanelsLayoutBlock =
|
42 |
+
/*#__PURE__*/
|
43 |
+
function (_Component) {
|
44 |
+
_inherits(SiteOriginPanelsLayoutBlock, _Component);
|
45 |
+
|
46 |
+
function SiteOriginPanelsLayoutBlock(props) {
|
47 |
+
var _this;
|
48 |
+
|
49 |
+
_classCallCheck(this, SiteOriginPanelsLayoutBlock);
|
50 |
+
|
51 |
+
_this = _possibleConstructorReturn(this, _getPrototypeOf(SiteOriginPanelsLayoutBlock).call(this, props));
|
52 |
+
var editMode = soPanelsBlockEditorAdmin.defaultMode === 'edit' || isEmpty(props.panelsData);
|
53 |
+
_this.state = {
|
54 |
+
editing: editMode,
|
55 |
+
loadingPreview: !editMode,
|
56 |
+
previewHtml: ''
|
57 |
+
};
|
58 |
+
_this.panelsContainer = createRef();
|
59 |
+
_this.previewContainer = createRef();
|
60 |
+
_this.panelsInitialized = false;
|
61 |
+
_this.previewInitialized = false;
|
62 |
+
return _this;
|
63 |
+
}
|
64 |
+
|
65 |
+
_createClass(SiteOriginPanelsLayoutBlock, [{
|
66 |
+
key: "componentDidMount",
|
67 |
+
value: function componentDidMount() {
|
68 |
+
this.isStillMounted = true;
|
69 |
+
|
70 |
+
if (this.state.editing) {
|
71 |
+
this.setupPanels();
|
72 |
+
} else if (!this.state.editing && !this.previewInitialized) {
|
73 |
+
this.fetchPreview(this.props);
|
74 |
+
this.fetchPreview = debounce(this.fetchPreview, 500);
|
75 |
+
}
|
76 |
+
}
|
77 |
+
}, {
|
78 |
+
key: "componentWillUnmount",
|
79 |
+
value: function componentWillUnmount() {
|
80 |
+
this.isStillMounted = false;
|
81 |
+
|
82 |
+
if (this.builderView) {
|
83 |
+
this.builderView.off('content_change');
|
84 |
+
}
|
85 |
+
}
|
86 |
+
}, {
|
87 |
+
key: "componentDidUpdate",
|
88 |
+
value: function componentDidUpdate(prevProps) {
|
89 |
+
// let propsChanged = !isEqual( prevProps.panelsData, this.props.panelsData );
|
90 |
+
if (this.state.editing && !this.panelsInitialized) {
|
91 |
+
this.setupPanels();
|
92 |
+
} else if (this.state.loadingPreview) {
|
93 |
+
this.fetchPreview(this.props);
|
94 |
+
} else if (!this.previewInitialized && this.previewContainer.current) {
|
95 |
+
$(document).trigger('panels_setup_preview');
|
96 |
+
this.previewInitialized = true;
|
97 |
+
}
|
98 |
+
}
|
99 |
+
}, {
|
100 |
+
key: "setupPanels",
|
101 |
+
value: function setupPanels() {
|
102 |
+
var _this2 = this;
|
103 |
+
|
104 |
+
var $panelsContainer = jQuery(this.panelsContainer.current);
|
105 |
+
var config = {
|
106 |
+
editorType: 'standalone'
|
107 |
+
};
|
108 |
+
var builderModel = new panels.model.builder();
|
109 |
+
this.builderView = new panels.view.builder({
|
110 |
+
model: builderModel,
|
111 |
+
config: config
|
112 |
+
}); // Make sure panelsData is defined and clone so that we don't alter the underlying attribute.
|
113 |
+
|
114 |
+
var panelsData = JSON.parse(JSON.stringify($.extend({}, this.props.panelsData))); // Disable block selection while dragging rows or widgets.
|
115 |
+
|
116 |
+
var rowOrWidgetMouseDown = function rowOrWidgetMouseDown() {
|
117 |
+
if (isFunction(_this2.props.onRowOrWidgetMouseDown)) {
|
118 |
+
_this2.props.onRowOrWidgetMouseDown();
|
119 |
+
}
|
120 |
+
|
121 |
+
var rowOrWidgetMouseUp = function rowOrWidgetMouseUp() {
|
122 |
+
$(document).off('mouseup', rowOrWidgetMouseUp);
|
123 |
+
|
124 |
+
if (isFunction(_this2.props.onRowOrWidgetMouseUp)) {
|
125 |
+
_this2.props.onRowOrWidgetMouseUp();
|
126 |
+
}
|
127 |
+
};
|
128 |
+
|
129 |
+
$(document).on('mouseup', rowOrWidgetMouseUp);
|
130 |
+
};
|
131 |
+
|
132 |
+
this.builderView.on('row_added', function () {
|
133 |
+
_this2.builderView.$('.so-row-move').off('mousedown', rowOrWidgetMouseDown);
|
134 |
+
|
135 |
+
_this2.builderView.$('.so-row-move').on('mousedown', rowOrWidgetMouseDown);
|
136 |
+
|
137 |
+
_this2.builderView.$('.so-widget').off('mousedown', rowOrWidgetMouseDown);
|
138 |
+
|
139 |
+
_this2.builderView.$('.so-widget').on('mousedown', rowOrWidgetMouseDown);
|
140 |
+
});
|
141 |
+
this.builderView.on('widget_added', function () {
|
142 |
+
_this2.builderView.$('.so-widget').off('mousedown', rowOrWidgetMouseDown);
|
143 |
+
|
144 |
+
_this2.builderView.$('.so-widget').on('mousedown', rowOrWidgetMouseDown);
|
145 |
+
});
|
146 |
+
this.builderView.render().attach({
|
147 |
+
container: $panelsContainer
|
148 |
+
}).setData(panelsData);
|
149 |
+
this.builderView.trigger('builder_resize');
|
150 |
+
this.builderView.on('content_change', function () {
|
151 |
+
var newPanelsData = _this2.builderView.getData();
|
152 |
+
|
153 |
+
_this2.panelsDataChanged = !isEqual(panelsData, newPanelsData);
|
154 |
+
|
155 |
+
if (_this2.panelsDataChanged) {
|
156 |
+
if (_this2.props.onContentChange && isFunction(_this2.props.onContentChange)) {
|
157 |
+
_this2.props.onContentChange(newPanelsData);
|
158 |
+
}
|
159 |
+
|
160 |
+
_this2.setState({
|
161 |
+
loadingPreview: true,
|
162 |
+
previewHtml: ''
|
163 |
+
});
|
164 |
+
}
|
165 |
+
});
|
166 |
+
$(document).trigger('panels_setup', this.builderView);
|
167 |
+
this.panelsInitialized = true;
|
168 |
+
}
|
169 |
+
}, {
|
170 |
+
key: "fetchPreview",
|
171 |
+
value: function fetchPreview(props) {
|
172 |
+
var _this3 = this;
|
173 |
+
|
174 |
+
if (!this.isStillMounted) {
|
175 |
+
return;
|
176 |
+
}
|
177 |
+
|
178 |
+
this.previewInitialized = false;
|
179 |
+
var fetchRequest = this.currentFetchRequest = $.post({
|
180 |
+
url: soPanelsBlockEditorAdmin.previewUrl,
|
181 |
+
data: {
|
182 |
+
action: 'so_panels_layout_block_preview',
|
183 |
+
panelsData: JSON.stringify(props.panelsData)
|
184 |
+
}
|
185 |
+
}).then(function (preview) {
|
186 |
+
if (_this3.isStillMounted && fetchRequest === _this3.currentFetchRequest && preview) {
|
187 |
+
_this3.setState({
|
188 |
+
previewHtml: preview,
|
189 |
+
loadingPreview: false
|
190 |
+
});
|
191 |
+
}
|
192 |
+
});
|
193 |
+
return fetchRequest;
|
194 |
+
}
|
195 |
+
}, {
|
196 |
+
key: "render",
|
197 |
+
value: function render() {
|
198 |
+
var _this4 = this;
|
199 |
+
|
200 |
+
var panelsData = this.props.panelsData;
|
201 |
+
|
202 |
+
var switchToEditing = function switchToEditing() {
|
203 |
+
_this4.panelsInitialized = false;
|
204 |
+
|
205 |
+
_this4.setState({
|
206 |
+
editing: true
|
207 |
+
});
|
208 |
+
};
|
209 |
+
|
210 |
+
var switchToPreview = function switchToPreview() {
|
211 |
+
if (panelsData) {
|
212 |
+
_this4.setState({
|
213 |
+
editing: false
|
214 |
+
});
|
215 |
+
}
|
216 |
+
};
|
217 |
+
|
218 |
+
if (this.state.editing) {
|
219 |
+
return React.createElement(Fragment, null, React.createElement(BlockControls, null, React.createElement(Toolbar, null, React.createElement(IconButton, {
|
220 |
+
icon: "visibility",
|
221 |
+
className: "components-icon-button components-toolbar__control",
|
222 |
+
label: __('Preview layout.', 'siteorigin-panels'),
|
223 |
+
onClick: switchToPreview
|
224 |
+
}))), React.createElement("div", {
|
225 |
+
key: "layout-block",
|
226 |
+
className: "siteorigin-panels-layout-block-container",
|
227 |
+
ref: this.panelsContainer
|
228 |
+
}));
|
229 |
+
} else {
|
230 |
+
var loadingPreview = this.state.loadingPreview;
|
231 |
+
return React.createElement(Fragment, null, React.createElement(BlockControls, null, React.createElement(Toolbar, null, React.createElement(IconButton, {
|
232 |
+
icon: "edit",
|
233 |
+
className: "components-icon-button components-toolbar__control",
|
234 |
+
label: __('Edit layout.', 'siteorigin-panels'),
|
235 |
+
onClick: switchToEditing
|
236 |
+
}))), React.createElement("div", {
|
237 |
+
key: "preview",
|
238 |
+
className: "so-panels-block-layout-preview-container"
|
239 |
+
}, loadingPreview ? React.createElement("div", {
|
240 |
+
className: "so-panels-spinner-container"
|
241 |
+
}, React.createElement("span", null, React.createElement(Spinner, null))) : React.createElement("div", {
|
242 |
+
className: "so-panels-raw-html-container",
|
243 |
+
ref: this.previewContainer
|
244 |
+
}, React.createElement(RawHTML, null, this.state.previewHtml))));
|
245 |
+
}
|
246 |
+
}
|
247 |
+
}]);
|
248 |
+
|
249 |
+
return SiteOriginPanelsLayoutBlock;
|
250 |
+
}(Component);
|
251 |
+
|
252 |
+
registerBlockType('siteorigin-panels/layout-block', {
|
253 |
+
title: __('SiteOrigin Layout', 'siteorigin-panels'),
|
254 |
+
description: __("Build a layout using SiteOrigin's Page Builder.", 'siteorigin-panels'),
|
255 |
+
icon: function icon() {
|
256 |
+
return React.createElement("span", {
|
257 |
+
className: "siteorigin-panels-block-icon"
|
258 |
+
});
|
259 |
+
},
|
260 |
+
category: 'layout',
|
261 |
+
keywords: ['page builder', 'column,grid', 'panel'],
|
262 |
+
supports: {
|
263 |
+
html: false
|
264 |
+
},
|
265 |
+
attributes: {
|
266 |
+
panelsData: {
|
267 |
+
type: 'object'
|
268 |
+
}
|
269 |
+
},
|
270 |
+
edit: function edit(_ref) {
|
271 |
+
var attributes = _ref.attributes,
|
272 |
+
setAttributes = _ref.setAttributes,
|
273 |
+
toggleSelection = _ref.toggleSelection;
|
274 |
+
|
275 |
+
var onLayoutBlockContentChange = function onLayoutBlockContentChange(newPanelsData) {
|
276 |
+
if (!_.isEmpty(newPanelsData.widgets)) {
|
277 |
+
// Send panelsData to server for sanitization.
|
278 |
+
$.post(soPanelsBlockEditorAdmin.sanitizeUrl, {
|
279 |
+
action: 'so_panels_layout_block_sanitize',
|
280 |
+
panelsData: JSON.stringify(newPanelsData)
|
281 |
+
}, function (sanitizedPanelsData) {
|
282 |
+
if (sanitizedPanelsData !== '') {
|
283 |
+
setAttributes({
|
284 |
+
panelsData: sanitizedPanelsData
|
285 |
+
});
|
286 |
+
}
|
287 |
+
});
|
288 |
+
}
|
289 |
+
};
|
290 |
+
|
291 |
+
var disableSelection = function disableSelection() {
|
292 |
+
toggleSelection(false);
|
293 |
+
};
|
294 |
+
|
295 |
+
var enableSelection = function enableSelection() {
|
296 |
+
toggleSelection(true);
|
297 |
+
};
|
298 |
+
|
299 |
+
return React.createElement(SiteOriginPanelsLayoutBlock, {
|
300 |
+
panelsData: attributes.panelsData,
|
301 |
+
onContentChange: onLayoutBlockContentChange,
|
302 |
+
onRowOrWidgetMouseDown: disableSelection,
|
303 |
+
onRowOrWidgetMouseUp: enableSelection
|
304 |
+
});
|
305 |
+
},
|
306 |
+
save: function save() {
|
307 |
+
// Render in PHP
|
308 |
+
return null;
|
309 |
+
}
|
310 |
+
});
|
311 |
+
|
312 |
+
(function ($) {
|
313 |
+
if (soPanelsBlockEditorAdmin.showAddButton) {
|
314 |
+
$(function () {
|
315 |
+
setTimeout(function () {
|
316 |
+
var editorDispatch = wp.data.dispatch('core/editor');
|
317 |
+
var editorSelect = wp.data.select('core/editor');
|
318 |
+
var tmpl = $('#siteorigin-panels-add-layout-block-button').html();
|
319 |
+
var $addButton = $(tmpl).insertAfter('.editor-writing-flow > div:first');
|
320 |
+
$addButton.on('click', function () {
|
321 |
+
var layoutBlock = wp.blocks.createBlock('siteorigin-panels/layout-block', {});
|
322 |
+
var isEmpty = editorSelect.isEditedPostEmpty();
|
323 |
+
|
324 |
+
if (isEmpty) {
|
325 |
+
var blocks = editorSelect.getBlocks();
|
326 |
+
|
327 |
+
if (blocks.length) {
|
328 |
+
editorDispatch.replaceBlock(blocks[0].clientId, layoutBlock);
|
329 |
+
} else {
|
330 |
+
editorDispatch.insertBlock(layoutBlock);
|
331 |
+
}
|
332 |
+
} else {
|
333 |
+
editorDispatch.insertBlock(layoutBlock);
|
334 |
+
}
|
335 |
+
});
|
336 |
+
|
337 |
+
var hideButtonIfBlocks = function hideButtonIfBlocks() {
|
338 |
+
var isEmpty = wp.data.select('core/editor').isEditedPostEmpty();
|
339 |
+
|
340 |
+
if (isEmpty) {
|
341 |
+
$addButton.show();
|
342 |
+
} else {
|
343 |
+
$addButton.hide();
|
344 |
+
}
|
345 |
+
};
|
346 |
+
|
347 |
+
wp.data.subscribe(hideButtonIfBlocks);
|
348 |
+
hideButtonIfBlocks();
|
349 |
+
}, 100);
|
350 |
+
});
|
351 |
+
}
|
352 |
})(jQuery);
|
inc/admin.php
CHANGED
@@ -78,7 +78,9 @@ class SiteOrigin_Panels_Admin {
|
|
78 |
add_filter( 'gutenberg_can_edit_post_type', array( $this, 'show_classic_editor_for_panels' ), 10, 2 );
|
79 |
add_filter( 'use_block_editor_for_post_type', array( $this, 'show_classic_editor_for_panels' ), 10, 2 );
|
80 |
add_action( 'admin_print_scripts-edit.php', array( $this, 'add_panels_add_new_button' ) );
|
81 |
-
|
|
|
|
|
82 |
}
|
83 |
}
|
84 |
|
78 |
add_filter( 'gutenberg_can_edit_post_type', array( $this, 'show_classic_editor_for_panels' ), 10, 2 );
|
79 |
add_filter( 'use_block_editor_for_post_type', array( $this, 'show_classic_editor_for_panels' ), 10, 2 );
|
80 |
add_action( 'admin_print_scripts-edit.php', array( $this, 'add_panels_add_new_button' ) );
|
81 |
+
if( siteorigin_panels_setting( 'admin-post-state' ) ) {
|
82 |
+
add_filter( 'display_post_states', array( $this, 'add_panels_post_state' ), 10, 2 );
|
83 |
+
}
|
84 |
}
|
85 |
}
|
86 |
|
inc/css-builder.php
CHANGED
@@ -109,7 +109,7 @@ class SiteOrigin_Panels_Css_Builder {
|
|
109 |
$selector[] = '#pl-' . $li;
|
110 |
}
|
111 |
$selector[] = is_string( $ri ) ? ( '#' . $ri ) : '#pg-' . $li . '-' . $ri;
|
112 |
-
$selector[] = '.panel-grid-cell';
|
113 |
} elseif ( $ri !== false && $ci !== false ) {
|
114 |
// This applies to a specific cell
|
115 |
if ( $specify_layout ) {
|
109 |
$selector[] = '#pl-' . $li;
|
110 |
}
|
111 |
$selector[] = is_string( $ri ) ? ( '#' . $ri ) : '#pg-' . $li . '-' . $ri;
|
112 |
+
$selector[] = '> .panel-grid-cell';
|
113 |
} elseif ( $ri !== false && $ci !== false ) {
|
114 |
// This applies to a specific cell
|
115 |
if ( $specify_layout ) {
|
inc/live-editor.php
CHANGED
@@ -9,7 +9,6 @@ class SiteOrigin_Panels_Live_Editor {
|
|
9 |
|
10 |
function __construct() {
|
11 |
add_action( 'template_redirect', array( $this, 'xss_headers' ) );
|
12 |
-
add_action( 'get_post_metadata', array( $this, 'post_metadata' ), 10, 3 );
|
13 |
add_action( 'wp_enqueue_scripts', array( $this, 'frontend_scripts' ) );
|
14 |
|
15 |
// Don't display the admin bar when in live editor mode
|
@@ -33,40 +32,6 @@ class SiteOrigin_Panels_Live_Editor {
|
|
33 |
}
|
34 |
}
|
35 |
|
36 |
-
/**
|
37 |
-
* Edit the page builder data when we're viewing the live editor version
|
38 |
-
*
|
39 |
-
* @param $value
|
40 |
-
* @param $post_id
|
41 |
-
* @param $meta_key
|
42 |
-
*
|
43 |
-
* @return array
|
44 |
-
*/
|
45 |
-
function post_metadata( $value, $post_id, $meta_key ) {
|
46 |
-
if (
|
47 |
-
$meta_key == 'panels_data' &&
|
48 |
-
current_user_can( 'edit_post', $post_id ) &&
|
49 |
-
! empty( $_POST['live_editor_panels_data'] ) &&
|
50 |
-
$_POST['live_editor_post_ID'] == $post_id
|
51 |
-
) {
|
52 |
-
$data = json_decode( wp_unslash( $_POST['live_editor_panels_data'] ), true );
|
53 |
-
|
54 |
-
if (
|
55 |
-
! empty( $data['widgets'] ) && (
|
56 |
-
! class_exists( 'SiteOrigin_Widget_Field_Class_Loader' ) ||
|
57 |
-
method_exists( 'SiteOrigin_Widget_Field_Class_Loader', 'extend' )
|
58 |
-
)
|
59 |
-
) {
|
60 |
-
$data['widgets'] = SiteOrigin_Panels_Admin::single()->process_raw_widgets( $data['widgets'], false, false );
|
61 |
-
}
|
62 |
-
|
63 |
-
$value = array( $data );
|
64 |
-
}
|
65 |
-
|
66 |
-
return $value;
|
67 |
-
}
|
68 |
-
|
69 |
-
|
70 |
/**
|
71 |
* Load the frontend scripts for the live editor
|
72 |
*/
|
9 |
|
10 |
function __construct() {
|
11 |
add_action( 'template_redirect', array( $this, 'xss_headers' ) );
|
|
|
12 |
add_action( 'wp_enqueue_scripts', array( $this, 'frontend_scripts' ) );
|
13 |
|
14 |
// Don't display the admin bar when in live editor mode
|
32 |
}
|
33 |
}
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
/**
|
36 |
* Load the frontend scripts for the live editor
|
37 |
*/
|
inc/renderer.php
CHANGED
@@ -210,11 +210,12 @@ class SiteOrigin_Panels_Renderer {
|
|
210 |
$css->add_cell_css( $post_id, $ri, false, '', array(
|
211 |
'margin-right' => 0,
|
212 |
), $panels_mobile_width );
|
|
|
|
|
|
|
|
|
213 |
}
|
214 |
|
215 |
-
$css->add_cell_css( $post_id, $ri, false, '', array(
|
216 |
-
'width' => '100%',
|
217 |
-
), $panels_mobile_width );
|
218 |
|
219 |
foreach ( $row['cells'] as $ci => $cell ) {
|
220 |
if ( ( $collapse_order == 'left-top' && $ci != $cell_count - 1 ) || ( $collapse_order == 'right-top' && $ci !== 0 ) ) {
|
@@ -602,7 +603,19 @@ class SiteOrigin_Panels_Renderer {
|
|
602 |
* @return array
|
603 |
*/
|
604 |
private function get_panels_data_for_post( $post_id ) {
|
605 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
606 |
list( $null, $prebuilt_id ) = explode( ':', $post_id, 2 );
|
607 |
$layouts = apply_filters( 'siteorigin_panels_prebuilt_layouts', array() );
|
608 |
$panels_data = ! empty( $layouts[ $prebuilt_id ] ) ? $layouts[ $prebuilt_id ] : array();
|
210 |
$css->add_cell_css( $post_id, $ri, false, '', array(
|
211 |
'margin-right' => 0,
|
212 |
), $panels_mobile_width );
|
213 |
+
|
214 |
+
$css->add_cell_css( $post_id, $ri, false, '', array(
|
215 |
+
'width' => '100%',
|
216 |
+
), $panels_mobile_width );
|
217 |
}
|
218 |
|
|
|
|
|
|
|
219 |
|
220 |
foreach ( $row['cells'] as $ci => $cell ) {
|
221 |
if ( ( $collapse_order == 'left-top' && $ci != $cell_count - 1 ) || ( $collapse_order == 'right-top' && $ci !== 0 ) ) {
|
603 |
* @return array
|
604 |
*/
|
605 |
private function get_panels_data_for_post( $post_id ) {
|
606 |
+
if ( SiteOrigin_Panels::is_live_editor() ) {
|
607 |
+
if (
|
608 |
+
current_user_can( 'edit_post', $post_id ) &&
|
609 |
+
! empty( $_POST['live_editor_panels_data'] ) &&
|
610 |
+
$_POST['live_editor_post_ID'] == $post_id
|
611 |
+
) {
|
612 |
+
$panels_data = json_decode( wp_unslash( $_POST['live_editor_panels_data'] ), true );
|
613 |
+
|
614 |
+
if ( ! empty( $panels_data['widgets'] ) ) {
|
615 |
+
$panels_data['widgets'] = SiteOrigin_Panels_Admin::single()->process_raw_widgets( $panels_data['widgets'] );
|
616 |
+
}
|
617 |
+
}
|
618 |
+
} else if ( strpos( $post_id, 'prebuilt:' ) === 0 ) {
|
619 |
list( $null, $prebuilt_id ) = explode( ':', $post_id, 2 );
|
620 |
$layouts = apply_filters( 'siteorigin_panels_prebuilt_layouts', array() );
|
621 |
$panels_data = ! empty( $layouts[ $prebuilt_id ] ) ? $layouts[ $prebuilt_id ] : array();
|
inc/settings.php
CHANGED
@@ -119,6 +119,7 @@ class SiteOrigin_Panels_Settings {
|
|
119 |
// The general fields
|
120 |
$defaults['post-types'] = array( 'page', 'post' );
|
121 |
$defaults['live-editor-quick-link'] = true;
|
|
|
122 |
$defaults['admin-widget-count'] = false;
|
123 |
$defaults['parallax-motion'] = '';
|
124 |
$defaults['sidebars-emulator'] = true;
|
@@ -261,6 +262,16 @@ class SiteOrigin_Panels_Settings {
|
|
261 |
'description' => __( 'Display a Live Editor button in the admin bar.', 'siteorigin-panels' ),
|
262 |
);
|
263 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
264 |
$fields['general']['fields']['admin-widget-count'] = array(
|
265 |
'type' => 'checkbox',
|
266 |
'label' => __( 'Display Widget Count', 'siteorigin-panels' ),
|
119 |
// The general fields
|
120 |
$defaults['post-types'] = array( 'page', 'post' );
|
121 |
$defaults['live-editor-quick-link'] = true;
|
122 |
+
$defaults['admin-post-state'] = true;
|
123 |
$defaults['admin-widget-count'] = false;
|
124 |
$defaults['parallax-motion'] = '';
|
125 |
$defaults['sidebars-emulator'] = true;
|
262 |
'description' => __( 'Display a Live Editor button in the admin bar.', 'siteorigin-panels' ),
|
263 |
);
|
264 |
|
265 |
+
$fields['general']['fields']['admin-post-state'] = array(
|
266 |
+
'type' => 'checkbox',
|
267 |
+
'label' => __( 'Display Post State', 'siteorigin-panels' ),
|
268 |
+
'description' => sprintf(
|
269 |
+
__( "Display a %sSiteOrigin Page Builder%s post state in the admin lists of posts/pages to indicate Page Builder is active.", 'siteorigin-panels' ),
|
270 |
+
'<strong>',
|
271 |
+
'</strong>'
|
272 |
+
),
|
273 |
+
);
|
274 |
+
|
275 |
$fields['general']['fields']['admin-widget-count'] = array(
|
276 |
'type' => 'checkbox',
|
277 |
'label' => __( 'Display Widget Count', 'siteorigin-panels' ),
|
inc/widgets/layout.php
CHANGED
@@ -58,14 +58,18 @@ class SiteOrigin_Panels_Widgets_Layout extends WP_Widget {
|
|
58 |
$new['panels_data'] = json_decode( $new['panels_data'], true );
|
59 |
}
|
60 |
|
61 |
-
if ( ! empty( $new['panels_data'] )
|
62 |
-
$new['panels_data']['widgets']
|
63 |
-
$new['panels_data']['widgets']
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
$
|
|
|
|
|
68 |
}
|
|
|
|
|
69 |
}
|
70 |
|
71 |
return $new;
|
58 |
$new['panels_data'] = json_decode( $new['panels_data'], true );
|
59 |
}
|
60 |
|
61 |
+
if ( ! empty( $new['panels_data'] ) ) {
|
62 |
+
if ( ! empty( $new['panels_data']['widgets'] ) ) {
|
63 |
+
$new['panels_data']['widgets'] = SiteOrigin_Panels_Admin::single()->process_raw_widgets(
|
64 |
+
$new['panels_data']['widgets'],
|
65 |
+
! empty( $old['panels_data']['widgets'] ) ? $old['panels_data']['widgets'] : false
|
66 |
+
);
|
67 |
+
foreach( $new['panels_data']['widgets'] as & $widget ) {
|
68 |
+
$widget['panels_info']['class'] = str_replace( '\\', '\', $widget['panels_info']['class'] );
|
69 |
+
}
|
70 |
}
|
71 |
+
|
72 |
+
$new['panels_data'] = SiteOrigin_Panels_Styles_Admin::single()->sanitize_all( $new['panels_data'] );
|
73 |
}
|
74 |
|
75 |
return $new;
|
js/siteorigin-panels-2101.js
DELETED
@@ -1,7438 +0,0 @@
|
|
1 |
-
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
2 |
-
var panels = window.panels;
|
3 |
-
|
4 |
-
module.exports = Backbone.Collection.extend( {
|
5 |
-
model: panels.model.cell,
|
6 |
-
|
7 |
-
initialize: function () {
|
8 |
-
},
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Get the total weight for the cells in this collection.
|
12 |
-
* @returns {number}
|
13 |
-
*/
|
14 |
-
totalWeight: function () {
|
15 |
-
var totalWeight = 0;
|
16 |
-
this.each( function ( cell ) {
|
17 |
-
totalWeight += cell.get( 'weight' );
|
18 |
-
} );
|
19 |
-
|
20 |
-
return totalWeight;
|
21 |
-
},
|
22 |
-
|
23 |
-
} );
|
24 |
-
|
25 |
-
},{}],2:[function(require,module,exports){
|
26 |
-
var panels = window.panels;
|
27 |
-
|
28 |
-
module.exports = Backbone.Collection.extend( {
|
29 |
-
model: panels.model.historyEntry,
|
30 |
-
|
31 |
-
/**
|
32 |
-
* The builder model
|
33 |
-
*/
|
34 |
-
builder: null,
|
35 |
-
|
36 |
-
/**
|
37 |
-
* The maximum number of items in the history
|
38 |
-
*/
|
39 |
-
maxSize: 12,
|
40 |
-
|
41 |
-
initialize: function () {
|
42 |
-
this.on( 'add', this.onAddEntry, this );
|
43 |
-
},
|
44 |
-
|
45 |
-
/**
|
46 |
-
* Add an entry to the collection.
|
47 |
-
*
|
48 |
-
* @param text The text that defines the action taken to get to this
|
49 |
-
* @param data
|
50 |
-
*/
|
51 |
-
addEntry: function ( text, data ) {
|
52 |
-
|
53 |
-
if ( _.isEmpty( data ) ) {
|
54 |
-
data = this.builder.getPanelsData();
|
55 |
-
}
|
56 |
-
|
57 |
-
var entry = new panels.model.historyEntry( {
|
58 |
-
text: text,
|
59 |
-
data: JSON.stringify( data ),
|
60 |
-
time: parseInt( new Date().getTime() / 1000 ),
|
61 |
-
collection: this
|
62 |
-
} );
|
63 |
-
|
64 |
-
this.add( entry );
|
65 |
-
},
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Resize the collection so it's not bigger than this.maxSize
|
69 |
-
*/
|
70 |
-
onAddEntry: function ( entry ) {
|
71 |
-
|
72 |
-
if ( this.models.length > 1 ) {
|
73 |
-
var lastEntry = this.at( this.models.length - 2 );
|
74 |
-
|
75 |
-
if (
|
76 |
-
(
|
77 |
-
entry.get( 'text' ) === lastEntry.get( 'text' ) && entry.get( 'time' ) - lastEntry.get( 'time' ) < 15
|
78 |
-
) ||
|
79 |
-
(
|
80 |
-
entry.get( 'data' ) === lastEntry.get( 'data' )
|
81 |
-
)
|
82 |
-
) {
|
83 |
-
// If both entries have the same text and are within 20 seconds of each other, or have the same data, then remove most recent
|
84 |
-
this.remove( entry );
|
85 |
-
lastEntry.set( 'count', lastEntry.get( 'count' ) + 1 );
|
86 |
-
}
|
87 |
-
}
|
88 |
-
|
89 |
-
// Make sure that there are not to many entries in this collection
|
90 |
-
while ( this.models.length > this.maxSize ) {
|
91 |
-
this.shift();
|
92 |
-
}
|
93 |
-
}
|
94 |
-
} );
|
95 |
-
|
96 |
-
},{}],3:[function(require,module,exports){
|
97 |
-
var panels = window.panels;
|
98 |
-
|
99 |
-
module.exports = Backbone.Collection.extend( {
|
100 |
-
model: panels.model.row,
|
101 |
-
|
102 |
-
/**
|
103 |
-
* Destroy all the rows in this collection
|
104 |
-
*/
|
105 |
-
empty: function () {
|
106 |
-
var model;
|
107 |
-
do {
|
108 |
-
model = this.collection.first();
|
109 |
-
if ( ! model ) {
|
110 |
-
break;
|
111 |
-
}
|
112 |
-
|
113 |
-
model.destroy();
|
114 |
-
} while ( true );
|
115 |
-
}
|
116 |
-
|
117 |
-
} );
|
118 |
-
|
119 |
-
},{}],4:[function(require,module,exports){
|
120 |
-
var panels = window.panels;
|
121 |
-
|
122 |
-
module.exports = Backbone.Collection.extend( {
|
123 |
-
model: panels.model.widget,
|
124 |
-
|
125 |
-
initialize: function () {
|
126 |
-
|
127 |
-
}
|
128 |
-
|
129 |
-
} );
|
130 |
-
|
131 |
-
},{}],5:[function(require,module,exports){
|
132 |
-
var panels = window.panels, $ = jQuery;
|
133 |
-
|
134 |
-
module.exports = panels.view.dialog.extend( {
|
135 |
-
dialogClass: 'so-panels-dialog-add-builder',
|
136 |
-
|
137 |
-
render: function () {
|
138 |
-
// Render the dialog and attach it to the builder interface
|
139 |
-
this.renderDialog( this.parseDialogContent( $( '#siteorigin-panels-dialog-builder' ).html(), {} ) );
|
140 |
-
this.$( '.so-content .siteorigin-panels-builder' ).append( this.builder.$el );
|
141 |
-
},
|
142 |
-
|
143 |
-
initializeDialog: function () {
|
144 |
-
var thisView = this;
|
145 |
-
this.once( 'open_dialog_complete', function () {
|
146 |
-
thisView.builder.initSortable();
|
147 |
-
} );
|
148 |
-
|
149 |
-
this.on( 'open_dialog_complete', function () {
|
150 |
-
thisView.builder.trigger( 'builder_resize' );
|
151 |
-
} );
|
152 |
-
}
|
153 |
-
} );
|
154 |
-
|
155 |
-
},{}],6:[function(require,module,exports){
|
156 |
-
var panels = window.panels, $ = jQuery;
|
157 |
-
|
158 |
-
module.exports = panels.view.dialog.extend( {
|
159 |
-
|
160 |
-
historyEntryTemplate: _.template( panels.helpers.utils.processTemplate( $( '#siteorigin-panels-dialog-history-entry' ).html() ) ),
|
161 |
-
|
162 |
-
entries: {},
|
163 |
-
currentEntry: null,
|
164 |
-
revertEntry: null,
|
165 |
-
selectedEntry: null,
|
166 |
-
|
167 |
-
previewScrollTop: null,
|
168 |
-
|
169 |
-
dialogClass: 'so-panels-dialog-history',
|
170 |
-
dialogIcon: 'history',
|
171 |
-
|
172 |
-
events: {
|
173 |
-
'click .so-close': 'closeDialog',
|
174 |
-
'click .so-restore': 'restoreSelectedEntry'
|
175 |
-
},
|
176 |
-
|
177 |
-
initializeDialog: function () {
|
178 |
-
this.entries = new panels.collection.historyEntries();
|
179 |
-
|
180 |
-
this.on( 'open_dialog', this.setCurrentEntry, this );
|
181 |
-
this.on( 'open_dialog', this.renderHistoryEntries, this );
|
182 |
-
},
|
183 |
-
|
184 |
-
render: function () {
|
185 |
-
var thisView = this;
|
186 |
-
|
187 |
-
// Render the dialog and attach it to the builder interface
|
188 |
-
this.renderDialog( this.parseDialogContent( $( '#siteorigin-panels-dialog-history' ).html(), {} ) );
|
189 |
-
|
190 |
-
this.$( 'iframe.siteorigin-panels-history-iframe' ).load( function () {
|
191 |
-
var $$ = $( this );
|
192 |
-
$$.show();
|
193 |
-
|
194 |
-
$$.contents().scrollTop( thisView.previewScrollTop );
|
195 |
-
} );
|
196 |
-
},
|
197 |
-
|
198 |
-
/**
|
199 |
-
* Set the original entry. This should be set when creating the dialog.
|
200 |
-
*
|
201 |
-
* @param {panels.model.builder} builder
|
202 |
-
*/
|
203 |
-
setRevertEntry: function ( builder ) {
|
204 |
-
this.revertEntry = new panels.model.historyEntry( {
|
205 |
-
data: JSON.stringify( builder.getPanelsData() ),
|
206 |
-
time: parseInt( new Date().getTime() / 1000 )
|
207 |
-
} );
|
208 |
-
},
|
209 |
-
|
210 |
-
/**
|
211 |
-
* This is triggered when the dialog is opened.
|
212 |
-
*/
|
213 |
-
setCurrentEntry: function () {
|
214 |
-
this.currentEntry = new panels.model.historyEntry( {
|
215 |
-
data: JSON.stringify( this.builder.model.getPanelsData() ),
|
216 |
-
time: parseInt( new Date().getTime() / 1000 )
|
217 |
-
} );
|
218 |
-
|
219 |
-
this.selectedEntry = this.currentEntry;
|
220 |
-
this.previewEntry( this.currentEntry );
|
221 |
-
this.$( '.so-buttons .so-restore' ).addClass( 'disabled' );
|
222 |
-
},
|
223 |
-
|
224 |
-
/**
|
225 |
-
* Render the history entries in the sidebar
|
226 |
-
*/
|
227 |
-
renderHistoryEntries: function () {
|
228 |
-
// Set up an interval that will display the time since every 10 seconds
|
229 |
-
var thisView = this;
|
230 |
-
|
231 |
-
var c = this.$( '.history-entries' ).empty();
|
232 |
-
|
233 |
-
if ( this.currentEntry.get( 'data' ) !== this.revertEntry.get( 'data' ) || ! _.isEmpty( this.entries.models ) ) {
|
234 |
-
$( this.historyEntryTemplate( {title: panelsOptions.loc.history.revert, count: 1} ) )
|
235 |
-
.data( 'historyEntry', this.revertEntry )
|
236 |
-
.prependTo( c );
|
237 |
-
}
|
238 |
-
|
239 |
-
// Now load all the entries in this.entries
|
240 |
-
this.entries.each( function ( entry ) {
|
241 |
-
|
242 |
-
var html = thisView.historyEntryTemplate( {
|
243 |
-
title: panelsOptions.loc.history[entry.get( 'text' )],
|
244 |
-
count: entry.get( 'count' )
|
245 |
-
} );
|
246 |
-
|
247 |
-
$( html )
|
248 |
-
.data( 'historyEntry', entry )
|
249 |
-
.prependTo( c );
|
250 |
-
} );
|
251 |
-
|
252 |
-
|
253 |
-
$( this.historyEntryTemplate( {title: panelsOptions.loc.history['current'], count: 1} ) )
|
254 |
-
.data( 'historyEntry', this.currentEntry )
|
255 |
-
.addClass( 'so-selected' )
|
256 |
-
.prependTo( c );
|
257 |
-
|
258 |
-
// Handle loading and selecting
|
259 |
-
c.find( '.history-entry' ).click( function () {
|
260 |
-
var $$ = jQuery( this );
|
261 |
-
c.find( '.history-entry' ).not( $$ ).removeClass( 'so-selected' );
|
262 |
-
$$.addClass( 'so-selected' );
|
263 |
-
|
264 |
-
var entry = $$.data( 'historyEntry' );
|
265 |
-
|
266 |
-
thisView.selectedEntry = entry;
|
267 |
-
|
268 |
-
if ( thisView.selectedEntry.cid !== thisView.currentEntry.cid ) {
|
269 |
-
thisView.$( '.so-buttons .so-restore' ).removeClass( 'disabled' );
|
270 |
-
} else {
|
271 |
-
thisView.$( '.so-buttons .so-restore' ).addClass( 'disabled' );
|
272 |
-
}
|
273 |
-
|
274 |
-
thisView.previewEntry( entry );
|
275 |
-
} );
|
276 |
-
|
277 |
-
this.updateEntryTimes();
|
278 |
-
},
|
279 |
-
|
280 |
-
/**
|
281 |
-
* Preview an entry
|
282 |
-
*
|
283 |
-
* @param entry
|
284 |
-
*/
|
285 |
-
previewEntry: function ( entry ) {
|
286 |
-
var iframe = this.$( 'iframe.siteorigin-panels-history-iframe' );
|
287 |
-
iframe.hide();
|
288 |
-
this.previewScrollTop = iframe.contents().scrollTop();
|
289 |
-
|
290 |
-
this.$( 'form.history-form input[name="live_editor_panels_data"]' ).val( entry.get( 'data' ) );
|
291 |
-
this.$( 'form.history-form input[name="live_editor_post_ID"]' ).val( this.builder.config.postId );
|
292 |
-
this.$( 'form.history-form' ).submit();
|
293 |
-
},
|
294 |
-
|
295 |
-
/**
|
296 |
-
* Restore the current entry
|
297 |
-
*/
|
298 |
-
restoreSelectedEntry: function () {
|
299 |
-
|
300 |
-
if ( this.$( '.so-buttons .so-restore' ).hasClass( 'disabled' ) ) {
|
301 |
-
return false;
|
302 |
-
}
|
303 |
-
|
304 |
-
if ( this.currentEntry.get( 'data' ) === this.selectedEntry.get( 'data' ) ) {
|
305 |
-
this.closeDialog();
|
306 |
-
return false;
|
307 |
-
}
|
308 |
-
|
309 |
-
// Add an entry for this restore event
|
310 |
-
if ( this.selectedEntry.get( 'text' ) !== 'restore' ) {
|
311 |
-
this.builder.addHistoryEntry( 'restore', this.builder.model.getPanelsData() );
|
312 |
-
}
|
313 |
-
|
314 |
-
this.builder.model.loadPanelsData( JSON.parse( this.selectedEntry.get( 'data' ) ) );
|
315 |
-
|
316 |
-
this.closeDialog();
|
317 |
-
|
318 |
-
return false;
|
319 |
-
},
|
320 |
-
|
321 |
-
/**
|
322 |
-
* Update the entry times for the list of entries down the side
|
323 |
-
*/
|
324 |
-
updateEntryTimes: function () {
|
325 |
-
var thisView = this;
|
326 |
-
|
327 |
-
this.$( '.history-entries .history-entry' ).each( function () {
|
328 |
-
var $$ = jQuery( this );
|
329 |
-
|
330 |
-
var time = $$.find( '.timesince' );
|
331 |
-
var entry = $$.data( 'historyEntry' );
|
332 |
-
|
333 |
-
time.html( thisView.timeSince( entry.get( 'time' ) ) );
|
334 |
-
} );
|
335 |
-
},
|
336 |
-
|
337 |
-
/**
|
338 |
-
* Gets the time since as a nice string.
|
339 |
-
*
|
340 |
-
* @param date
|
341 |
-
*/
|
342 |
-
timeSince: function ( time ) {
|
343 |
-
var diff = parseInt( new Date().getTime() / 1000 ) - time;
|
344 |
-
|
345 |
-
var parts = [];
|
346 |
-
var interval;
|
347 |
-
|
348 |
-
// There are 3600 seconds in an hour
|
349 |
-
if ( diff > 3600 ) {
|
350 |
-
interval = Math.floor( diff / 3600 );
|
351 |
-
if ( interval === 1 ) {
|
352 |
-
parts.push( panelsOptions.loc.time.hour.replace( '%d', interval ) );
|
353 |
-
} else {
|
354 |
-
parts.push( panelsOptions.loc.time.hours.replace( '%d', interval ) );
|
355 |
-
}
|
356 |
-
diff -= interval * 3600;
|
357 |
-
}
|
358 |
-
|
359 |
-
// There are 60 seconds in a minute
|
360 |
-
if ( diff > 60 ) {
|
361 |
-
interval = Math.floor( diff / 60 );
|
362 |
-
if ( interval === 1 ) {
|
363 |
-
parts.push( panelsOptions.loc.time.minute.replace( '%d', interval ) );
|
364 |
-
} else {
|
365 |
-
parts.push( panelsOptions.loc.time.minutes.replace( '%d', interval ) );
|
366 |
-
}
|
367 |
-
diff -= interval * 60;
|
368 |
-
}
|
369 |
-
|
370 |
-
if ( diff > 0 ) {
|
371 |
-
if ( diff === 1 ) {
|
372 |
-
parts.push( panelsOptions.loc.time.second.replace( '%d', diff ) );
|
373 |
-
} else {
|
374 |
-
parts.push( panelsOptions.loc.time.seconds.replace( '%d', diff ) );
|
375 |
-
}
|
376 |
-
}
|
377 |
-
|
378 |
-
// Return the amount of time ago
|
379 |
-
return _.isEmpty( parts ) ? panelsOptions.loc.time.now : panelsOptions.loc.time.ago.replace( '%s', parts.slice( 0, 2 ).join( ', ' ) );
|
380 |
-
|
381 |
-
}
|
382 |
-
|
383 |
-
} );
|
384 |
-
|
385 |
-
},{}],7:[function(require,module,exports){
|
386 |
-
var panels = window.panels, $ = jQuery;
|
387 |
-
|
388 |
-
module.exports = panels.view.dialog.extend( {
|
389 |
-
|
390 |
-
directoryTemplate: _.template( panels.helpers.utils.processTemplate( $( '#siteorigin-panels-directory-items' ).html() ) ),
|
391 |
-
|
392 |
-
builder: null,
|
393 |
-
dialogClass: 'so-panels-dialog-prebuilt-layouts',
|
394 |
-
dialogIcon: 'layouts',
|
395 |
-
|
396 |
-
layoutCache: {},
|
397 |
-
currentTab: false,
|
398 |
-
directoryPage: 1,
|
399 |
-
|
400 |
-
events: {
|
401 |
-
'click .so-close': 'closeDialog',
|
402 |
-
'click .so-sidebar-tabs li a': 'tabClickHandler',
|
403 |
-
'click .so-content .layout': 'layoutClickHandler',
|
404 |
-
'keyup .so-sidebar-search': 'searchHandler',
|
405 |
-
|
406 |
-
// The directory items
|
407 |
-
'click .so-screenshot, .so-title': 'directoryItemClickHandler'
|
408 |
-
},
|
409 |
-
|
410 |
-
/**
|
411 |
-
* Initialize the prebuilt dialog.
|
412 |
-
*/
|
413 |
-
initializeDialog: function () {
|
414 |
-
var thisView = this;
|
415 |
-
|
416 |
-
this.on( 'open_dialog', function () {
|
417 |
-
thisView.$( '.so-sidebar-tabs li a' ).first().click();
|
418 |
-
thisView.$( '.so-status' ).removeClass( 'so-panels-loading' );
|
419 |
-
} );
|
420 |
-
|
421 |
-
this.on( 'button_click', this.toolbarButtonClick, this );
|
422 |
-
},
|
423 |
-
|
424 |
-
/**
|
425 |
-
* Render the prebuilt layouts dialog
|
426 |
-
*/
|
427 |
-
render: function () {
|
428 |
-
this.renderDialog( this.parseDialogContent( $( '#siteorigin-panels-dialog-prebuilt' ).html(), {} ) );
|
429 |
-
|
430 |
-
this.initToolbar();
|
431 |
-
},
|
432 |
-
|
433 |
-
/**
|
434 |
-
*
|
435 |
-
* @param e
|
436 |
-
* @return {boolean}
|
437 |
-
*/
|
438 |
-
tabClickHandler: function ( e ) {
|
439 |
-
e.preventDefault();
|
440 |
-
// Reset selected item state when changing tabs
|
441 |
-
this.selectedLayoutItem = null;
|
442 |
-
this.uploadedLayout = null;
|
443 |
-
this.updateButtonState( false );
|
444 |
-
|
445 |
-
this.$( '.so-sidebar-tabs li' ).removeClass( 'tab-active' );
|
446 |
-
|
447 |
-
var $$ = $( e.target );
|
448 |
-
var tab = $$.attr( 'href' ).split( '#' )[1];
|
449 |
-
$$.parent().addClass( 'tab-active' );
|
450 |
-
|
451 |
-
var thisView = this;
|
452 |
-
|
453 |
-
// Empty everything
|
454 |
-
this.$( '.so-content' ).empty();
|
455 |
-
|
456 |
-
thisView.currentTab = tab;
|
457 |
-
if ( tab == 'import' ) {
|
458 |
-
this.displayImportExport();
|
459 |
-
} else {
|
460 |
-
this.displayLayoutDirectory( '', 1, tab );
|
461 |
-
}
|
462 |
-
|
463 |
-
thisView.$( '.so-sidebar-search' ).val( '' );
|
464 |
-
},
|
465 |
-
|
466 |
-
/**
|
467 |
-
* Display and setup the import/export form
|
468 |
-
*/
|
469 |
-
displayImportExport: function () {
|
470 |
-
var c = this.$( '.so-content' ).empty().removeClass( 'so-panels-loading' );
|
471 |
-
c.html( $( '#siteorigin-panels-dialog-prebuilt-importexport' ).html() );
|
472 |
-
|
473 |
-
var thisView = this;
|
474 |
-
var uploadUi = thisView.$( '.import-upload-ui' );
|
475 |
-
|
476 |
-
// Create the uploader
|
477 |
-
var uploader = new plupload.Uploader( {
|
478 |
-
runtimes: 'html5,silverlight,flash,html4',
|
479 |
-
|
480 |
-
browse_button: uploadUi.find( '.file-browse-button' ).get( 0 ),
|
481 |
-
container: uploadUi.get( 0 ),
|
482 |
-
drop_element: uploadUi.find( '.drag-upload-area' ).get( 0 ),
|
483 |
-
|
484 |
-
file_data_name: 'panels_import_data',
|
485 |
-
multiple_queues: false,
|
486 |
-
max_file_size: panelsOptions.plupload.max_file_size,
|
487 |
-
url: panelsOptions.plupload.url,
|
488 |
-
flash_swf_url: panelsOptions.plupload.flash_swf_url,
|
489 |
-
silverlight_xap_url: panelsOptions.plupload.silverlight_xap_url,
|
490 |
-
filters: [
|
491 |
-
{title: panelsOptions.plupload.filter_title, extensions: 'json'}
|
492 |
-
],
|
493 |
-
|
494 |
-
multipart_params: {
|
495 |
-
action: 'so_panels_import_layout'
|
496 |
-
},
|
497 |
-
|
498 |
-
init: {
|
499 |
-
PostInit: function ( uploader ) {
|
500 |
-
if ( uploader.features.dragdrop ) {
|
501 |
-
uploadUi.addClass( 'has-drag-drop' );
|
502 |
-
}
|
503 |
-
uploadUi.find( '.progress-precent' ).css( 'width', '0%' );
|
504 |
-
},
|
505 |
-
FilesAdded: function ( uploader ) {
|
506 |
-
uploadUi.find( '.file-browse-button' ).blur();
|
507 |
-
uploadUi.find( '.drag-upload-area' ).removeClass( 'file-dragover' );
|
508 |
-
uploadUi.find( '.progress-bar' ).fadeIn( 'fast' );
|
509 |
-
thisView.$( '.js-so-selected-file' ).text( panelsOptions.loc.prebuilt_loading );
|
510 |
-
uploader.start();
|
511 |
-
},
|
512 |
-
UploadProgress: function ( uploader, file ) {
|
513 |
-
uploadUi.find( '.progress-precent' ).css( 'width', file.percent + '%' );
|
514 |
-
},
|
515 |
-
FileUploaded: function ( uploader, file, response ) {
|
516 |
-
var layout = JSON.parse( response.response );
|
517 |
-
if ( ! _.isUndefined( layout.widgets ) ) {
|
518 |
-
|
519 |
-
thisView.uploadedLayout = layout;
|
520 |
-
uploadUi.find( '.progress-bar' ).hide();
|
521 |
-
thisView.$( '.js-so-selected-file' ).text(
|
522 |
-
panelsOptions.loc.ready_to_insert.replace( '%s', file.name )
|
523 |
-
);
|
524 |
-
thisView.updateButtonState( true );
|
525 |
-
} else {
|
526 |
-
alert( panelsOptions.plupload.error_message );
|
527 |
-
}
|
528 |
-
},
|
529 |
-
Error: function () {
|
530 |
-
alert( panelsOptions.plupload.error_message );
|
531 |
-
}
|
532 |
-
}
|
533 |
-
} );
|
534 |
-
uploader.init();
|
535 |
-
|
536 |
-
if ( /Edge\/\d./i.test(navigator.userAgent) ){
|
537 |
-
// A very dirty fix for a Microsoft Edge issue.
|
538 |
-
// TODO find a more elegant fix if Edge gains market share
|
539 |
-
setTimeout( function(){
|
540 |
-
uploader.refresh();
|
541 |
-
}, 250 );
|
542 |
-
}
|
543 |
-
|
544 |
-
// This is
|
545 |
-
uploadUi.find( '.drag-upload-area' )
|
546 |
-
.on( 'dragover', function () {
|
547 |
-
$( this ).addClass( 'file-dragover' );
|
548 |
-
} )
|
549 |
-
.on( 'dragleave', function () {
|
550 |
-
$( this ).removeClass( 'file-dragover' );
|
551 |
-
} );
|
552 |
-
|
553 |
-
// Handle exporting the file
|
554 |
-
c.find( '.so-export' ).submit( function ( e ) {
|
555 |
-
var $$ = $( this );
|
556 |
-
var panelsData = thisView.builder.model.getPanelsData();
|
557 |
-
var postName = $('input[name="post_title"]').val();
|
558 |
-
if ( ! postName ) {
|
559 |
-
postName = $('input[name="post_ID"]').val();
|
560 |
-
}
|
561 |
-
panelsData.name = postName;
|
562 |
-
$$.find( 'input[name="panels_export_data"]' ).val( JSON.stringify( panelsData ) );
|
563 |
-
} );
|
564 |
-
|
565 |
-
},
|
566 |
-
|
567 |
-
/**
|
568 |
-
* Display the layout directory tab.
|
569 |
-
*
|
570 |
-
* @param query
|
571 |
-
*/
|
572 |
-
displayLayoutDirectory: function ( search, page, type ) {
|
573 |
-
var thisView = this;
|
574 |
-
var c = this.$( '.so-content' ).empty().addClass( 'so-panels-loading' );
|
575 |
-
|
576 |
-
if ( search === undefined ) {
|
577 |
-
search = '';
|
578 |
-
}
|
579 |
-
if ( page === undefined ) {
|
580 |
-
page = 1;
|
581 |
-
}
|
582 |
-
if ( type === undefined ) {
|
583 |
-
type = 'directory-siteorigin';
|
584 |
-
}
|
585 |
-
|
586 |
-
if ( type.match('^directory-') && ! panelsOptions.directory_enabled ) {
|
587 |
-
// Display the button to enable the prebuilt layout
|
588 |
-
c.removeClass( 'so-panels-loading' ).html( $( '#siteorigin-panels-directory-enable' ).html() );
|
589 |
-
c.find( '.so-panels-enable-directory' ).click( function ( e ) {
|
590 |
-
e.preventDefault();
|
591 |
-
// Sent the query to enable the directory, then enable the directory
|
592 |
-
$.get(
|
593 |
-
panelsOptions.ajaxurl,
|
594 |
-
{action: 'so_panels_directory_enable'},
|
595 |
-
function () {
|
596 |
-
|
597 |
-
}
|
598 |
-
);
|
599 |
-
|
600 |
-
// Enable the layout directory
|
601 |
-
panelsOptions.directory_enabled = true;
|
602 |
-
c.addClass( 'so-panels-loading' );
|
603 |
-
thisView.displayLayoutDirectory( search, page, type );
|
604 |
-
} );
|
605 |
-
return;
|
606 |
-
}
|
607 |
-
|
608 |
-
// Get all the items for the current query
|
609 |
-
$.get(
|
610 |
-
panelsOptions.ajaxurl,
|
611 |
-
{
|
612 |
-
action: 'so_panels_layouts_query',
|
613 |
-
search: search,
|
614 |
-
page: page,
|
615 |
-
type: type,
|
616 |
-
},
|
617 |
-
function ( data ) {
|
618 |
-
// Skip this if we're no longer viewing the layout directory
|
619 |
-
if ( thisView.currentTab !== type ) {
|
620 |
-
return;
|
621 |
-
}
|
622 |
-
|
623 |
-
// Add the directory items
|
624 |
-
c.removeClass( 'so-panels-loading' ).html( thisView.directoryTemplate( data ) );
|
625 |
-
|
626 |
-
// Lets setup the next and previous buttons
|
627 |
-
var prev = c.find( '.so-previous' ), next = c.find( '.so-next' );
|
628 |
-
|
629 |
-
if ( page <= 1 ) {
|
630 |
-
prev.addClass( 'button-disabled' );
|
631 |
-
} else {
|
632 |
-
prev.click( function ( e ) {
|
633 |
-
e.preventDefault();
|
634 |
-
thisView.displayLayoutDirectory( search, page - 1, thisView.currentTab );
|
635 |
-
} );
|
636 |
-
}
|
637 |
-
|
638 |
-
if ( page === data.max_num_pages || data.max_num_pages === 0 ) {
|
639 |
-
next.addClass( 'button-disabled' );
|
640 |
-
} else {
|
641 |
-
next.click( function ( e ) {
|
642 |
-
e.preventDefault();
|
643 |
-
thisView.displayLayoutDirectory( search, page + 1, thisView.currentTab );
|
644 |
-
} );
|
645 |
-
}
|
646 |
-
|
647 |
-
// Handle nice preloading of the screenshots
|
648 |
-
c.find( '.so-screenshot' ).each( function () {
|
649 |
-
var $$ = $( this ), $a = $$.find( '.so-screenshot-wrapper' );
|
650 |
-
$a.css( 'height', ( $a.width() / 4 * 3 ) + 'px' ).addClass( 'so-loading' );
|
651 |
-
|
652 |
-
if ( $$.data( 'src' ) !== '' ) {
|
653 |
-
// Set the initial height
|
654 |
-
var $img = $( '<img/>' ).attr( 'src', $$.data( 'src' ) ).load( function () {
|
655 |
-
$a.removeClass( 'so-loading' ).css( 'height', 'auto' );
|
656 |
-
$img.appendTo( $a ).hide().fadeIn( 'fast' );
|
657 |
-
} );
|
658 |
-
} else {
|
659 |
-
$( '<img/>' ).attr( 'src', panelsOptions.prebuiltDefaultScreenshot ).appendTo( $a ).hide().fadeIn( 'fast' );
|
660 |
-
}
|
661 |
-
|
662 |
-
} );
|
663 |
-
|
664 |
-
// Set the title
|
665 |
-
c.find( '.so-directory-browse' ).html( data.title );
|
666 |
-
},
|
667 |
-
'json'
|
668 |
-
);
|
669 |
-
},
|
670 |
-
|
671 |
-
/**
|
672 |
-
* Set the selected state for the clicked layout directory item and remove previously selected item.
|
673 |
-
* Enable the toolbar buttons.
|
674 |
-
*/
|
675 |
-
directoryItemClickHandler: function ( e ) {
|
676 |
-
var $directoryItem = this.$( e.target ).closest( '.so-directory-item' );
|
677 |
-
this.$( '.so-directory-items' ).find( '.selected' ).removeClass( 'selected' );
|
678 |
-
$directoryItem.addClass( 'selected' );
|
679 |
-
this.selectedLayoutItem = {lid: $directoryItem.data( 'layout-id' ), type: $directoryItem.data( 'layout-type' )};
|
680 |
-
this.updateButtonState( true );
|
681 |
-
|
682 |
-
},
|
683 |
-
|
684 |
-
/**
|
685 |
-
* Load a particular layout into the builder.
|
686 |
-
*
|
687 |
-
* @param id
|
688 |
-
*/
|
689 |
-
toolbarButtonClick: function ( $button ) {
|
690 |
-
if ( ! this.canAddLayout() ) {
|
691 |
-
return false;
|
692 |
-
}
|
693 |
-
var position = $button.data( 'value' );
|
694 |
-
if ( _.isUndefined( position ) ) {
|
695 |
-
return false;
|
696 |
-
}
|
697 |
-
this.updateButtonState( false );
|
698 |
-
|
699 |
-
if ( $button.hasClass( 'so-needs-confirm' ) && ! $button.hasClass( 'so-confirmed' ) ) {
|
700 |
-
this.updateButtonState( true );
|
701 |
-
if ( $button.hasClass( 'so-confirming' ) ) {
|
702 |
-
return;
|
703 |
-
}
|
704 |
-
$button.addClass( 'so-confirming' );
|
705 |
-
var originalText = $button.html();
|
706 |
-
$button.html( '<span class="dashicons dashicons-yes"></span>' + $button.data( 'confirm' ) );
|
707 |
-
setTimeout( function () {
|
708 |
-
$button.removeClass( 'so-confirmed' ).html( originalText );
|
709 |
-
}, 2500 );
|
710 |
-
setTimeout( function () {
|
711 |
-
$button.removeClass( 'so-confirming' );
|
712 |
-
$button.addClass( 'so-confirmed' );
|
713 |
-
}, 200 );
|
714 |
-
return false;
|
715 |
-
}
|
716 |
-
this.addingLayout = true;
|
717 |
-
if ( this.currentTab === 'import' ) {
|
718 |
-
this.addLayoutToBuilder( this.uploadedLayout, position );
|
719 |
-
} else {
|
720 |
-
this.loadSelectedLayout().then( function ( layout ) {
|
721 |
-
this.addLayoutToBuilder( layout, position );
|
722 |
-
}.bind( this ) );
|
723 |
-
}
|
724 |
-
},
|
725 |
-
|
726 |
-
canAddLayout: function () {
|
727 |
-
return (
|
728 |
-
this.selectedLayoutItem || this.uploadedLayout
|
729 |
-
) && ! this.addingLayout;
|
730 |
-
},
|
731 |
-
|
732 |
-
/**
|
733 |
-
* Load the layout according to selectedLayoutItem.
|
734 |
-
*/
|
735 |
-
loadSelectedLayout: function () {
|
736 |
-
this.setStatusMessage( panelsOptions.loc.prebuilt_loading, true );
|
737 |
-
|
738 |
-
var args = _.extend( this.selectedLayoutItem, {action: 'so_panels_get_layout'} );
|
739 |
-
var deferredLayout = new $.Deferred();
|
740 |
-
|
741 |
-
$.get(
|
742 |
-
panelsOptions.ajaxurl,
|
743 |
-
args,
|
744 |
-
function ( layout ) {
|
745 |
-
var msg = '';
|
746 |
-
if ( ! layout.success ) {
|
747 |
-
msg = layout.data.message;
|
748 |
-
deferredLayout.reject( layout.data );
|
749 |
-
} else {
|
750 |
-
deferredLayout.resolve( layout.data );
|
751 |
-
}
|
752 |
-
this.setStatusMessage( msg, false, ! layout.success );
|
753 |
-
this.updateButtonState( true );
|
754 |
-
}.bind( this )
|
755 |
-
);
|
756 |
-
return deferredLayout.promise();
|
757 |
-
},
|
758 |
-
|
759 |
-
/**
|
760 |
-
* Handle an update to the search
|
761 |
-
*/
|
762 |
-
searchHandler: function ( e ) {
|
763 |
-
if ( e.keyCode === 13 ) {
|
764 |
-
this.displayLayoutDirectory( $( e.currentTarget ).val(), 1, this.currentTab );
|
765 |
-
}
|
766 |
-
},
|
767 |
-
|
768 |
-
/**
|
769 |
-
* Attempt to set the 'Insert' button's state according to the `enabled` argument, also checking whether the
|
770 |
-
* requirements for inserting a layout have valid values.
|
771 |
-
*/
|
772 |
-
updateButtonState: function ( enabled ) {
|
773 |
-
enabled = enabled && (
|
774 |
-
this.selectedLayoutItem || this.uploadedLayout
|
775 |
-
);
|
776 |
-
var $button = this.$( '.so-import-layout' );
|
777 |
-
$button.prop( "disabled", ! enabled );
|
778 |
-
if ( enabled ) {
|
779 |
-
$button.removeClass( 'disabled' );
|
780 |
-
} else {
|
781 |
-
$button.addClass( 'disabled' );
|
782 |
-
}
|
783 |
-
},
|
784 |
-
|
785 |
-
addLayoutToBuilder: function ( layout, position ) {
|
786 |
-
this.builder.addHistoryEntry( 'prebuilt_loaded' );
|
787 |
-
this.builder.model.loadPanelsData( layout, position );
|
788 |
-
this.addingLayout = false;
|
789 |
-
this.closeDialog();
|
790 |
-
}
|
791 |
-
} );
|
792 |
-
|
793 |
-
},{}],8:[function(require,module,exports){
|
794 |
-
var panels = window.panels, $ = jQuery;
|
795 |
-
|
796 |
-
module.exports = panels.view.dialog.extend({
|
797 |
-
|
798 |
-
cellPreviewTemplate: _.template( panels.helpers.utils.processTemplate( $('#siteorigin-panels-dialog-row-cell-preview').html() ) ),
|
799 |
-
|
800 |
-
editableLabel: true,
|
801 |
-
|
802 |
-
events: {
|
803 |
-
'click .so-close': 'closeDialog',
|
804 |
-
|
805 |
-
// Toolbar buttons
|
806 |
-
'click .so-toolbar .so-save': 'saveHandler',
|
807 |
-
'click .so-toolbar .so-insert': 'insertHandler',
|
808 |
-
'click .so-toolbar .so-delete': 'deleteHandler',
|
809 |
-
'click .so-toolbar .so-duplicate': 'duplicateHandler',
|
810 |
-
|
811 |
-
// Changing the row
|
812 |
-
'change .row-set-form > *': 'setCellsFromForm',
|
813 |
-
'click .row-set-form button.set-row': 'setCellsFromForm',
|
814 |
-
},
|
815 |
-
|
816 |
-
rowView: null,
|
817 |
-
dialogIcon: 'add-row',
|
818 |
-
dialogClass: 'so-panels-dialog-row-edit',
|
819 |
-
styleType: 'row',
|
820 |
-
|
821 |
-
dialogType: 'edit',
|
822 |
-
|
823 |
-
/**
|
824 |
-
* The current settings, not yet saved to the model
|
825 |
-
*/
|
826 |
-
row: {
|
827 |
-
// This will be a clone of cells collection.
|
828 |
-
cells: null,
|
829 |
-
// The style settings of the row
|
830 |
-
style: {}
|
831 |
-
},
|
832 |
-
|
833 |
-
cellStylesCache: [],
|
834 |
-
|
835 |
-
initializeDialog: function () {
|
836 |
-
this.on('open_dialog', function () {
|
837 |
-
if (!_.isUndefined(this.model) && !_.isEmpty(this.model.get('cells'))) {
|
838 |
-
this.setRowModel(this.model);
|
839 |
-
} else {
|
840 |
-
this.setRowModel(null);
|
841 |
-
}
|
842 |
-
|
843 |
-
this.regenerateRowPreview();
|
844 |
-
this.renderStyles();
|
845 |
-
}, this);
|
846 |
-
|
847 |
-
// This is the default row layout
|
848 |
-
this.row = {
|
849 |
-
cells: new panels.collection.cells([{weight: 0.5}, {weight: 0.5}]),
|
850 |
-
style: {}
|
851 |
-
};
|
852 |
-
|
853 |
-
// Refresh panels data after both dialog form components are loaded
|
854 |
-
this.dialogFormsLoaded = 0;
|
855 |
-
var thisView = this;
|
856 |
-
this.on('form_loaded styles_loaded', function () {
|
857 |
-
this.dialogFormsLoaded++;
|
858 |
-
if (this.dialogFormsLoaded === 2) {
|
859 |
-
thisView.updateModel({
|
860 |
-
refreshArgs: {
|
861 |
-
silent: true
|
862 |
-
}
|
863 |
-
});
|
864 |
-
}
|
865 |
-
});
|
866 |
-
|
867 |
-
this.on('close_dialog', this.closeHandler);
|
868 |
-
|
869 |
-
this.on( 'edit_label', function ( text ) {
|
870 |
-
// If text is set to default values, just clear it.
|
871 |
-
if ( text === panelsOptions.loc.row.add || text === panelsOptions.loc.row.edit ) {
|
872 |
-
text = '';
|
873 |
-
}
|
874 |
-
this.model.set( 'label', text );
|
875 |
-
if ( _.isEmpty( text ) ) {
|
876 |
-
var title = this.dialogType === 'create' ? panelsOptions.loc.row.add : panelsOptions.loc.row.edit;
|
877 |
-
this.$( '.so-title').text( title );
|
878 |
-
}
|
879 |
-
}.bind( this ) );
|
880 |
-
},
|
881 |
-
|
882 |
-
/**
|
883 |
-
*
|
884 |
-
* @param dialogType Either "edit" or "create"
|
885 |
-
*/
|
886 |
-
setRowDialogType: function (dialogType) {
|
887 |
-
this.dialogType = dialogType;
|
888 |
-
},
|
889 |
-
|
890 |
-
/**
|
891 |
-
* Render the new row dialog
|
892 |
-
*/
|
893 |
-
render: function () {
|
894 |
-
var title = this.dialogType === 'create' ? panelsOptions.loc.row.add : panelsOptions.loc.row.edit;
|
895 |
-
this.renderDialog( this.parseDialogContent( $( '#siteorigin-panels-dialog-row' ).html(), {
|
896 |
-
title: title,
|
897 |
-
dialogType: this.dialogType
|
898 |
-
} ) );
|
899 |
-
|
900 |
-
var titleElt = this.$( '.so-title' );
|
901 |
-
|
902 |
-
if ( this.model.has( 'label' ) && ! _.isEmpty( this.model.get( 'label' ) ) ) {
|
903 |
-
titleElt.text( this.model.get( 'label' ) );
|
904 |
-
}
|
905 |
-
this.$( '.so-edit-title' ).val( titleElt.text() );
|
906 |
-
|
907 |
-
if (!this.builder.supports('addRow')) {
|
908 |
-
this.$('.so-buttons .so-duplicate').remove();
|
909 |
-
}
|
910 |
-
if (!this.builder.supports('deleteRow')) {
|
911 |
-
this.$('.so-buttons .so-delete').remove();
|
912 |
-
}
|
913 |
-
|
914 |
-
if (!_.isUndefined(this.model)) {
|
915 |
-
// Set the initial value of the
|
916 |
-
this.$( 'input[name="cells"].so-row-field' ).val( this.model.get( 'cells' ).length );
|
917 |
-
if ( this.model.has( 'ratio' ) ) {
|
918 |
-
this.$( 'select[name="ratio"].so-row-field' ).val( this.model.get( 'ratio' ) );
|
919 |
-
}
|
920 |
-
if ( this.model.has( 'ratio_direction' ) ) {
|
921 |
-
this.$( 'select[name="ratio_direction"].so-row-field' ).val( this.model.get( 'ratio_direction' ) );
|
922 |
-
}
|
923 |
-
}
|
924 |
-
|
925 |
-
this.$('input.so-row-field').keyup(function () {
|
926 |
-
$(this).trigger('change');
|
927 |
-
});
|
928 |
-
|
929 |
-
return this;
|
930 |
-
},
|
931 |
-
|
932 |
-
renderStyles: function () {
|
933 |
-
if ( this.styles ) {
|
934 |
-
this.styles.off( 'styles_loaded' );
|
935 |
-
this.styles.remove();
|
936 |
-
}
|
937 |
-
|
938 |
-
// Now we need to attach the style window
|
939 |
-
this.styles = new panels.view.styles();
|
940 |
-
this.styles.model = this.model;
|
941 |
-
this.styles.render('row', this.builder.config.postId, {
|
942 |
-
builderType: this.builder.config.builderType,
|
943 |
-
dialog: this
|
944 |
-
});
|
945 |
-
|
946 |
-
var $rightSidebar = this.$('.so-sidebar.so-right-sidebar');
|
947 |
-
this.styles.attach( $rightSidebar );
|
948 |
-
|
949 |
-
// Handle the loading class
|
950 |
-
this.styles.on('styles_loaded', function (hasStyles) {
|
951 |
-
if ( ! hasStyles ) {
|
952 |
-
// If we don't have styles remove the view.
|
953 |
-
this.styles.remove();
|
954 |
-
|
955 |
-
// If the sidebar is empty, hide it.
|
956 |
-
if ( $rightSidebar.children().length === 0 ) {
|
957 |
-
$rightSidebar.closest('.so-panels-dialog').removeClass('so-panels-dialog-has-right-sidebar');
|
958 |
-
$rightSidebar.hide();
|
959 |
-
}
|
960 |
-
}
|
961 |
-
}, this);
|
962 |
-
},
|
963 |
-
|
964 |
-
/**
|
965 |
-
* Set the row model we'll be using for this dialog.
|
966 |
-
*
|
967 |
-
* @param model
|
968 |
-
*/
|
969 |
-
setRowModel: function (model) {
|
970 |
-
this.model = model;
|
971 |
-
|
972 |
-
if (_.isEmpty(this.model)) {
|
973 |
-
return this;
|
974 |
-
}
|
975 |
-
|
976 |
-
// Set the rows to be a copy of the model
|
977 |
-
this.row = {
|
978 |
-
cells: this.model.get('cells').clone(),
|
979 |
-
style: {},
|
980 |
-
ratio: this.model.get('ratio'),
|
981 |
-
ratio_direction: this.model.get('ratio_direction'),
|
982 |
-
};
|
983 |
-
|
984 |
-
// Set the initial value of the cell field.
|
985 |
-
this.$( 'input[name="cells"].so-row-field' ).val( this.model.get( 'cells' ).length );
|
986 |
-
if ( this.model.has( 'ratio' ) ) {
|
987 |
-
this.$( 'select[name="ratio"].so-row-field' ).val( this.model.get( 'ratio' ) );
|
988 |
-
}
|
989 |
-
if ( this.model.has( 'ratio_direction' ) ) {
|
990 |
-
this.$( 'select[name="ratio_direction"].so-row-field' ).val( this.model.get( 'ratio_direction' ) );
|
991 |
-
}
|
992 |
-
|
993 |
-
this.clearCellStylesCache();
|
994 |
-
|
995 |
-
return this;
|
996 |
-
},
|
997 |
-
|
998 |
-
/**
|
999 |
-
* Regenerate the row preview and resizing interface.
|
1000 |
-
*/
|
1001 |
-
regenerateRowPreview: function () {
|
1002 |
-
var thisDialog = this;
|
1003 |
-
var rowPreview = this.$('.row-preview');
|
1004 |
-
|
1005 |
-
// If no selected cell, select the first cell.
|
1006 |
-
var selectedIndex = this.getSelectedCellIndex();
|
1007 |
-
|
1008 |
-
rowPreview.empty();
|
1009 |
-
|
1010 |
-
var timeout;
|
1011 |
-
|
1012 |
-
// Represent the cells
|
1013 |
-
this.row.cells.each(function (cellModel, i) {
|
1014 |
-
var newCell = $(this.cellPreviewTemplate({weight: cellModel.get('weight')}));
|
1015 |
-
rowPreview.append(newCell);
|
1016 |
-
|
1017 |
-
if(i == selectedIndex) {
|
1018 |
-
newCell.find('.preview-cell-in').addClass('cell-selected');
|
1019 |
-
}
|
1020 |
-
|
1021 |
-
var prevCell = newCell.prev();
|
1022 |
-
var handle;
|
1023 |
-
|
1024 |
-
if (prevCell.length) {
|
1025 |
-
handle = $('<div class="resize-handle"></div>');
|
1026 |
-
handle
|
1027 |
-
.appendTo(newCell)
|
1028 |
-
.dblclick(function () {
|
1029 |
-
var prevCellModel = thisDialog.row.cells.at(i - 1);
|
1030 |
-
var t = cellModel.get('weight') + prevCellModel.get('weight');
|
1031 |
-
cellModel.set('weight', t / 2);
|
1032 |
-
prevCellModel.set('weight', t / 2);
|
1033 |
-
thisDialog.scaleRowWidths();
|
1034 |
-
});
|
1035 |
-
|
1036 |
-
handle.draggable({
|
1037 |
-
axis: 'x',
|
1038 |
-
containment: rowPreview,
|
1039 |
-
start: function (e, ui) {
|
1040 |
-
|
1041 |
-
// Create the clone for the current cell
|
1042 |
-
var newCellClone = newCell.clone().appendTo(ui.helper).css({
|
1043 |
-
position: 'absolute',
|
1044 |
-
top: '0',
|
1045 |
-
width: newCell.outerWidth(),
|
1046 |
-
left: 6,
|
1047 |
-
height: newCell.outerHeight()
|
1048 |
-
});
|
1049 |
-
newCellClone.find('.resize-handle').remove();
|
1050 |
-
|
1051 |
-
// Create the clone for the previous cell
|
1052 |
-
var prevCellClone = prevCell.clone().appendTo(ui.helper).css({
|
1053 |
-
position: 'absolute',
|
1054 |
-
top: '0',
|
1055 |
-
width: prevCell.outerWidth(),
|
1056 |
-
right: 6,
|
1057 |
-
height: prevCell.outerHeight()
|
1058 |
-
});
|
1059 |
-
prevCellClone.find('.resize-handle').remove();
|
1060 |
-
|
1061 |
-
$(this).data({
|
1062 |
-
'newCellClone': newCellClone,
|
1063 |
-
'prevCellClone': prevCellClone
|
1064 |
-
});
|
1065 |
-
|
1066 |
-
// Hide the
|
1067 |
-
newCell.find('> .preview-cell-in').css('visibility', 'hidden');
|
1068 |
-
prevCell.find('> .preview-cell-in').css('visibility', 'hidden');
|
1069 |
-
},
|
1070 |
-
drag: function (e, ui) {
|
1071 |
-
// Calculate the new cell and previous cell widths as a percent
|
1072 |
-
var cellWeight = thisDialog.row.cells.at(i).get('weight');
|
1073 |
-
var prevCellWeight = thisDialog.row.cells.at(i - 1).get('weight');
|
1074 |
-
var ncw = cellWeight - (
|
1075 |
-
(
|
1076 |
-
ui.position.left + 6
|
1077 |
-
) / rowPreview.width()
|
1078 |
-
);
|
1079 |
-
var pcw = prevCellWeight + (
|
1080 |
-
(
|
1081 |
-
ui.position.left + 6
|
1082 |
-
) / rowPreview.width()
|
1083 |
-
);
|
1084 |
-
|
1085 |
-
var helperLeft = ui.helper.offset().left - rowPreview.offset().left - 6;
|
1086 |
-
|
1087 |
-
$(this).data('newCellClone').css('width', rowPreview.width() * ncw)
|
1088 |
-
.find('.preview-cell-weight').html(Math.round(ncw * 1000) / 10);
|
1089 |
-
|
1090 |
-
$(this).data('prevCellClone').css('width', rowPreview.width() * pcw)
|
1091 |
-
.find('.preview-cell-weight').html(Math.round(pcw * 1000) / 10);
|
1092 |
-
},
|
1093 |
-
stop: function (e, ui) {
|
1094 |
-
// Remove the clones
|
1095 |
-
$(this).data('newCellClone').remove();
|
1096 |
-
$(this).data('prevCellClone').remove();
|
1097 |
-
|
1098 |
-
// Reshow the main cells
|
1099 |
-
newCell.find('.preview-cell-in').css('visibility', 'visible');
|
1100 |
-
prevCell.find('.preview-cell-in').css('visibility', 'visible');
|
1101 |
-
|
1102 |
-
// Calculate the new cell weights
|
1103 |
-
var offset = ui.position.left + 6;
|
1104 |
-
var percent = offset / rowPreview.width();
|
1105 |
-
|
1106 |
-
// Ignore this if any of the cells are below 2% in width.
|
1107 |
-
var cellModel = thisDialog.row.cells.at(i);
|
1108 |
-
var prevCellModel = thisDialog.row.cells.at(i - 1);
|
1109 |
-
if (cellModel.get('weight') - percent > 0.02 && prevCellModel.get('weight') + percent > 0.02) {
|
1110 |
-
cellModel.set('weight', cellModel.get('weight') - percent);
|
1111 |
-
prevCellModel.set('weight', prevCellModel.get('weight') + percent);
|
1112 |
-
}
|
1113 |
-
|
1114 |
-
thisDialog.scaleRowWidths();
|
1115 |
-
ui.helper.css('left', -6);
|
1116 |
-
}
|
1117 |
-
});
|
1118 |
-
}
|
1119 |
-
|
1120 |
-
newCell.click(function (event) {
|
1121 |
-
|
1122 |
-
if ( ! ( $(event.target).is('.preview-cell') || $(event.target).is('.preview-cell-in') ) ) {
|
1123 |
-
return;
|
1124 |
-
}
|
1125 |
-
|
1126 |
-
var cell = $(event.target);
|
1127 |
-
cell.closest('.row-preview').find('.preview-cell .preview-cell-in').removeClass('cell-selected');
|
1128 |
-
cell.addClass('cell-selected');
|
1129 |
-
|
1130 |
-
this.openSelectedCellStyles();
|
1131 |
-
|
1132 |
-
}.bind(this));
|
1133 |
-
|
1134 |
-
// Make this row weight click editable
|
1135 |
-
newCell.find('.preview-cell-weight').click(function (ci) {
|
1136 |
-
|
1137 |
-
// Disable the draggable while entering values
|
1138 |
-
thisDialog.$('.resize-handle').css('pointer-event', 'none').draggable('disable');
|
1139 |
-
|
1140 |
-
rowPreview.find('.preview-cell-weight').each(function () {
|
1141 |
-
var $$ = jQuery(this).hide();
|
1142 |
-
$('<input type="text" class="preview-cell-weight-input no-user-interacted" />')
|
1143 |
-
.val(parseFloat($$.html())).insertAfter($$)
|
1144 |
-
.focus(function () {
|
1145 |
-
clearTimeout(timeout);
|
1146 |
-
})
|
1147 |
-
.keyup(function (e) {
|
1148 |
-
if (e.keyCode !== 9) {
|
1149 |
-
// Only register the interaction if the user didn't press tab
|
1150 |
-
$(this).removeClass('no-user-interacted');
|
1151 |
-
}
|
1152 |
-
|
1153 |
-
// Enter is clicked
|
1154 |
-
if (e.keyCode === 13) {
|
1155 |
-
e.preventDefault();
|
1156 |
-
$(this).blur();
|
1157 |
-
}
|
1158 |
-
})
|
1159 |
-
.keydown(function (e) {
|
1160 |
-
if (e.keyCode === 9) {
|
1161 |
-
e.preventDefault();
|
1162 |
-
|
1163 |
-
// Tab will always cycle around the row inputs
|
1164 |
-
var inputs = rowPreview.find('.preview-cell-weight-input');
|
1165 |
-
var i = inputs.index($(this));
|
1166 |
-
if (i === inputs.length - 1) {
|
1167 |
-
inputs.eq(0).focus().select();
|
1168 |
-
} else {
|
1169 |
-
inputs.eq(i + 1).focus().select();
|
1170 |
-
}
|
1171 |
-
}
|
1172 |
-
})
|
1173 |
-
.blur(function () {
|
1174 |
-
rowPreview.find('.preview-cell-weight-input').each(function (i, el) {
|
1175 |
-
if (isNaN(parseFloat($(el).val()))) {
|
1176 |
-
$(el).val(Math.floor(thisDialog.row.cells.at(i).get('weight') * 1000) / 10);
|
1177 |
-
}
|
1178 |
-
});
|
1179 |
-
|
1180 |
-
timeout = setTimeout(function () {
|
1181 |
-
// If there are no weight inputs, then skip this
|
1182 |
-
if (rowPreview.find('.preview-cell-weight-input').length === 0) {
|
1183 |
-
return false;
|
1184 |
-
}
|
1185 |
-
|
1186 |
-
// Go through all the inputs
|
1187 |
-
var rowWeights = [],
|
1188 |
-
rowChanged = [],
|
1189 |
-
changedSum = 0,
|
1190 |
-
unchangedSum = 0;
|
1191 |
-
|
1192 |
-
rowPreview.find('.preview-cell-weight-input').each(function (i, el) {
|
1193 |
-
var val = parseFloat($(el).val());
|
1194 |
-
if (isNaN(val)) {
|
1195 |
-
val = 1 / thisDialog.row.cells.length;
|
1196 |
-
} else {
|
1197 |
-
val = Math.round(val * 10) / 1000;
|
1198 |
-
}
|
1199 |
-
|
1200 |
-
// Check within 3 decimal points
|
1201 |
-
var changed = !$(el).hasClass('no-user-interacted');
|
1202 |
-
|
1203 |
-
rowWeights.push(val);
|
1204 |
-
rowChanged.push(changed);
|
1205 |
-
|
1206 |
-
if (changed) {
|
1207 |
-
changedSum += val;
|
1208 |
-
} else {
|
1209 |
-
unchangedSum += val;
|
1210 |
-
}
|
1211 |
-
});
|
1212 |
-
|
1213 |
-
if (changedSum > 0 && unchangedSum > 0 && (
|
1214 |
-
1 - changedSum
|
1215 |
-
) > 0) {
|
1216 |
-
// Balance out the unchanged rows to occupy the weight left over by the changed sum
|
1217 |
-
for (var i = 0; i < rowWeights.length; i++) {
|
1218 |
-
if (!rowChanged[i]) {
|
1219 |
-
rowWeights[i] = (
|
1220 |
-
rowWeights[i] / unchangedSum
|
1221 |
-
) * (
|
1222 |
-
1 - changedSum
|
1223 |
-
);
|
1224 |
-
}
|
1225 |
-
}
|
1226 |
-
}
|
1227 |
-
|
1228 |
-
// Last check to ensure total weight is 1
|
1229 |
-
var sum = _.reduce(rowWeights, function (memo, num) {
|
1230 |
-
return memo + num;
|
1231 |
-
});
|
1232 |
-
rowWeights = rowWeights.map(function (w) {
|
1233 |
-
return w / sum;
|
1234 |
-
});
|
1235 |
-
|
1236 |
-
// Set the new cell weights and regenerate the preview.
|
1237 |
-
if (Math.min.apply(Math, rowWeights) > 0.01) {
|
1238 |
-
thisDialog.row.cells.each(function (cell, i) {
|
1239 |
-
cell.set('weight', rowWeights[i]);
|
1240 |
-
});
|
1241 |
-
}
|
1242 |
-
|
1243 |
-
// Now lets animate the cells into their new widths
|
1244 |
-
rowPreview.find('.preview-cell').each(function (i, el) {
|
1245 |
-
var cellWeight = thisDialog.row.cells.at(i).get('weight');
|
1246 |
-
$(el).animate({'width': Math.round(cellWeight * 1000) / 10 + "%"}, 250);
|
1247 |
-
$(el).find('.preview-cell-weight-input').val(Math.round(cellWeight * 1000) / 10);
|
1248 |
-
});
|
1249 |
-
|
1250 |
-
// So the draggable handle is not hidden.
|
1251 |
-
rowPreview.find('.preview-cell').css('overflow', 'visible');
|
1252 |
-
setTimeout(thisDialog.regenerateRowPreview.bind(thisDialog), 260);
|
1253 |
-
|
1254 |
-
}, 100);
|
1255 |
-
})
|
1256 |
-
.click(function () {
|
1257 |
-
$(this).select();
|
1258 |
-
});
|
1259 |
-
});
|
1260 |
-
|
1261 |
-
$(this).siblings('.preview-cell-weight-input').select();
|
1262 |
-
|
1263 |
-
});
|
1264 |
-
|
1265 |
-
}, this);
|
1266 |
-
|
1267 |
-
this.openSelectedCellStyles();
|
1268 |
-
|
1269 |
-
this.trigger('form_loaded', this);
|
1270 |
-
},
|
1271 |
-
|
1272 |
-
getSelectedCellIndex: function() {
|
1273 |
-
var selectedIndex = -1;
|
1274 |
-
this.$('.preview-cell .preview-cell-in').each(function(index, el) {
|
1275 |
-
if($(el).is('.cell-selected')) {
|
1276 |
-
selectedIndex = index;
|
1277 |
-
}
|
1278 |
-
});
|
1279 |
-
return selectedIndex;
|
1280 |
-
},
|
1281 |
-
|
1282 |
-
openSelectedCellStyles: function() {
|
1283 |
-
if (!_.isUndefined(this.cellStyles)) {
|
1284 |
-
if (this.cellStyles.stylesLoaded) {
|
1285 |
-
var style = {};
|
1286 |
-
try {
|
1287 |
-
style = this.getFormValues('.so-sidebar .so-visual-styles.so-cell-styles').style;
|
1288 |
-
}
|
1289 |
-
catch (err) {
|
1290 |
-
console.log('Error retrieving cell styles - ' + err.message);
|
1291 |
-
}
|
1292 |
-
|
1293 |
-
this.cellStyles.model.set('style', style);
|
1294 |
-
}
|
1295 |
-
this.cellStyles.detach();
|
1296 |
-
}
|
1297 |
-
|
1298 |
-
this.cellStyles = this.getSelectedCellStyles();
|
1299 |
-
|
1300 |
-
if ( this.cellStyles ) {
|
1301 |
-
var $rightSidebar = this.$( '.so-sidebar.so-right-sidebar' );
|
1302 |
-
this.cellStyles.attach( $rightSidebar );
|
1303 |
-
this.cellStyles.on( 'styles_loaded', function ( hasStyles ) {
|
1304 |
-
if ( hasStyles ) {
|
1305 |
-
$rightSidebar.closest('.so-panels-dialog').addClass('so-panels-dialog-has-right-sidebar');
|
1306 |
-
$rightSidebar.show();
|
1307 |
-
}
|
1308 |
-
} );
|
1309 |
-
}
|
1310 |
-
},
|
1311 |
-
|
1312 |
-
getSelectedCellStyles: function () {
|
1313 |
-
var cellIndex = this.getSelectedCellIndex();
|
1314 |
-
if ( cellIndex > -1 ) {
|
1315 |
-
var cellStyles = this.cellStylesCache[cellIndex];
|
1316 |
-
if ( !cellStyles ) {
|
1317 |
-
cellStyles = new panels.view.styles();
|
1318 |
-
cellStyles.model = this.row.cells.at( cellIndex );
|
1319 |
-
cellStyles.render( 'cell', this.builder.config.postId, {
|
1320 |
-
builderType: this.builder.config.builderType,
|
1321 |
-
dialog: this,
|
1322 |
-
index: cellIndex,
|
1323 |
-
} );
|
1324 |
-
this.cellStylesCache[cellIndex] = cellStyles;
|
1325 |
-
}
|
1326 |
-
}
|
1327 |
-
|
1328 |
-
return cellStyles;
|
1329 |
-
},
|
1330 |
-
|
1331 |
-
clearCellStylesCache: function () {
|
1332 |
-
// Call remove() on all cell styles to remove data, event listeners etc.
|
1333 |
-
this.cellStylesCache.forEach(function (cellStyles) {
|
1334 |
-
cellStyles.remove();
|
1335 |
-
});
|
1336 |
-
this.cellStylesCache = [];
|
1337 |
-
},
|
1338 |
-
|
1339 |
-
/**
|
1340 |
-
* Visually scale the row widths based on the cell weights
|
1341 |
-
*/
|
1342 |
-
scaleRowWidths: function () {
|
1343 |
-
var thisDialog = this;
|
1344 |
-
this.$('.row-preview .preview-cell').each(function (i, el) {
|
1345 |
-
var cell = thisDialog.row.cells.at(i);
|
1346 |
-
$(el)
|
1347 |
-
.css('width', cell.get('weight') * 100 + "%")
|
1348 |
-
.find('.preview-cell-weight').html(Math.round(cell.get('weight') * 1000) / 10);
|
1349 |
-
});
|
1350 |
-
},
|
1351 |
-
|
1352 |
-
/**
|
1353 |
-
* Get the weights from the
|
1354 |
-
*/
|
1355 |
-
setCellsFromForm: function () {
|
1356 |
-
|
1357 |
-
try {
|
1358 |
-
var f = {
|
1359 |
-
'cells': parseInt(this.$('.row-set-form input[name="cells"]').val()),
|
1360 |
-
'ratio': parseFloat(this.$('.row-set-form select[name="ratio"]').val()),
|
1361 |
-
'direction': this.$('.row-set-form select[name="ratio_direction"]').val()
|
1362 |
-
};
|
1363 |
-
|
1364 |
-
if (_.isNaN(f.cells)) {
|
1365 |
-
f.cells = 1;
|
1366 |
-
}
|
1367 |
-
if (isNaN(f.ratio)) {
|
1368 |
-
f.ratio = 1;
|
1369 |
-
}
|
1370 |
-
if (f.cells < 1) {
|
1371 |
-
f.cells = 1;
|
1372 |
-
this.$('.row-set-form input[name="cells"]').val(f.cells);
|
1373 |
-
}
|
1374 |
-
else if (f.cells > 12) {
|
1375 |
-
f.cells = 12;
|
1376 |
-
this.$('.row-set-form input[name="cells"]').val(f.cells);
|
1377 |
-
}
|
1378 |
-
|
1379 |
-
this.$('.row-set-form select[name="ratio"]').val(f.ratio);
|
1380 |
-
|
1381 |
-
var cells = [];
|
1382 |
-
var cellCountChanged = (
|
1383 |
-
this.row.cells.length !== f.cells
|
1384 |
-
);
|
1385 |
-
|
1386 |
-
// Now, lets create some cells
|
1387 |
-
var currentWeight = 1;
|
1388 |
-
for (var i = 0; i < f.cells; i++) {
|
1389 |
-
cells.push(currentWeight);
|
1390 |
-
currentWeight *= f.ratio;
|
1391 |
-
}
|
1392 |
-
|
1393 |
-
// Now lets make sure that the row weights add up to 1
|
1394 |
-
|
1395 |
-
var totalRowWeight = _.reduce(cells, function (memo, weight) {
|
1396 |
-
return memo + weight;
|
1397 |
-
});
|
1398 |
-
cells = _.map(cells, function (cell) {
|
1399 |
-
return cell / totalRowWeight;
|
1400 |
-
});
|
1401 |
-
|
1402 |
-
// Don't return cells that are too small
|
1403 |
-
cells = _.filter(cells, function (cell) {
|
1404 |
-
return cell > 0.01;
|
1405 |
-
});
|
1406 |
-
|
1407 |
-
if (f.direction === 'left') {
|
1408 |
-
cells = cells.reverse();
|
1409 |
-
}
|
1410 |
-
|
1411 |
-
// Discard deleted cells.
|
1412 |
-
this.row.cells = new panels.collection.cells(this.row.cells.first(cells.length));
|
1413 |
-
|
1414 |
-
_.each(cells, function (cellWeight, index) {
|
1415 |
-
var cell = this.row.cells.at(index);
|
1416 |
-
if (!cell) {
|
1417 |
-
cell = new panels.model.cell({weight: cellWeight, row: this.model});
|
1418 |
-
this.row.cells.add(cell);
|
1419 |
-
} else {
|
1420 |
-
cell.set('weight', cellWeight);
|
1421 |
-
}
|
1422 |
-
}.bind(this));
|
1423 |
-
|
1424 |
-
this.row.ratio = f.ratio;
|
1425 |
-
this.row.ratio_direction = f.direction;
|
1426 |
-
|
1427 |
-
if (cellCountChanged) {
|
1428 |
-
this.regenerateRowPreview();
|
1429 |
-
} else {
|
1430 |
-
var thisDialog = this;
|
1431 |
-
|
1432 |
-
// Now lets animate the cells into their new widths
|
1433 |
-
this.$('.preview-cell').each(function (i, el) {
|
1434 |
-
var cellWeight = thisDialog.row.cells.at(i).get('weight');
|
1435 |
-
$(el).animate({'width': Math.round(cellWeight * 1000) / 10 + "%"}, 250);
|
1436 |
-
$(el).find('.preview-cell-weight').html(Math.round(cellWeight * 1000) / 10);
|
1437 |
-
});
|
1438 |
-
|
1439 |
-
// So the draggable handle is not hidden.
|
1440 |
-
this.$('.preview-cell').css('overflow', 'visible');
|
1441 |
-
|
1442 |
-
setTimeout(thisDialog.regenerateRowPreview.bind(thisDialog), 260);
|
1443 |
-
}
|
1444 |
-
}
|
1445 |
-
catch (err) {
|
1446 |
-
console.log('Error setting cells - ' + err.message);
|
1447 |
-
}
|
1448 |
-
|
1449 |
-
|
1450 |
-
// Remove the button primary class
|
1451 |
-
this.$('.row-set-form .so-button-row-set').removeClass('button-primary');
|
1452 |
-
},
|
1453 |
-
|
1454 |
-
/**
|
1455 |
-
* Handle a click on the dialog left bar tab
|
1456 |
-
*/
|
1457 |
-
tabClickHandler: function ($t) {
|
1458 |
-
if ($t.attr('href') === '#row-layout') {
|
1459 |
-
this.$('.so-panels-dialog').addClass('so-panels-dialog-has-right-sidebar');
|
1460 |
-
} else {
|
1461 |
-
this.$('.so-panels-dialog').removeClass('so-panels-dialog-has-right-sidebar');
|
1462 |
-
}
|
1463 |
-
},
|
1464 |
-
|
1465 |
-
/**
|
1466 |
-
* Update the current model with what we have in the dialog
|
1467 |
-
*/
|
1468 |
-
updateModel: function (args) {
|
1469 |
-
args = _.extend({
|
1470 |
-
refresh: true,
|
1471 |
-
refreshArgs: null
|
1472 |
-
}, args);
|
1473 |
-
|
1474 |
-
// Set the cells
|
1475 |
-
if (!_.isEmpty(this.model)) {
|
1476 |
-
this.model.setCells( this.row.cells );
|
1477 |
-
this.model.set( 'ratio', this.row.ratio );
|
1478 |
-
this.model.set( 'ratio_direction', this.row.ratio_direction );
|
1479 |
-
}
|
1480 |
-
|
1481 |
-
// Update the row styles if they've loaded
|
1482 |
-
if (!_.isUndefined(this.styles) && this.styles.stylesLoaded) {
|
1483 |
-
// This is an edit dialog, so there are styles
|
1484 |
-
var style = {};
|
1485 |
-
try {
|
1486 |
-
style = this.getFormValues('.so-sidebar .so-visual-styles.so-row-styles').style;
|
1487 |
-
}
|
1488 |
-
catch (err) {
|
1489 |
-
console.log('Error retrieving row styles - ' + err.message);
|
1490 |
-
}
|
1491 |
-
|
1492 |
-
this.model.set('style', style);
|
1493 |
-
}
|
1494 |
-
|
1495 |
-
// Update the cell styles if any are showing.
|
1496 |
-
if (!_.isUndefined(this.cellStyles) && this.cellStyles.stylesLoaded) {
|
1497 |
-
|
1498 |
-
var style = {};
|
1499 |
-
try {
|
1500 |
-
style = this.getFormValues('.so-sidebar .so-visual-styles.so-cell-styles').style;
|
1501 |
-
}
|
1502 |
-
catch (err) {
|
1503 |
-
console.log('Error retrieving cell styles - ' + err.message);
|
1504 |
-
}
|
1505 |
-
|
1506 |
-
this.cellStyles.model.set('style', style);
|
1507 |
-
}
|
1508 |
-
|
1509 |
-
if (args.refresh) {
|
1510 |
-
this.builder.model.refreshPanelsData(args.refreshArgs);
|
1511 |
-
}
|
1512 |
-
},
|
1513 |
-
|
1514 |
-
/**
|
1515 |
-
* Insert the new row
|
1516 |
-
*/
|
1517 |
-
insertHandler: function () {
|
1518 |
-
this.builder.addHistoryEntry('row_added');
|
1519 |
-
|
1520 |
-
this.updateModel();
|
1521 |
-
|
1522 |
-
var activeCell = this.builder.getActiveCell({
|
1523 |
-
createCell: false,
|
1524 |
-
});
|
1525 |
-
|
1526 |
-
var options = {};
|
1527 |
-
if (activeCell !== null) {
|
1528 |
-
options.at = this.builder.model.get('rows').indexOf(activeCell.row) + 1;
|
1529 |
-
}
|
1530 |
-
|
1531 |
-
// Set up the model and add it to the builder
|
1532 |
-
this.model.collection = this.builder.model.get('rows');
|
1533 |
-
this.builder.model.get('rows').add(this.model, options);
|
1534 |
-
|
1535 |
-
this.closeDialog();
|
1536 |
-
|
1537 |
-
this.builder.model.refreshPanelsData();
|
1538 |
-
|
1539 |
-
return false;
|
1540 |
-
},
|
1541 |
-
|
1542 |
-
/**
|
1543 |
-
* We'll just save this model and close the dialog
|
1544 |
-
*/
|
1545 |
-
saveHandler: function () {
|
1546 |
-
this.builder.addHistoryEntry('row_edited');
|
1547 |
-
this.updateModel();
|
1548 |
-
this.closeDialog();
|
1549 |
-
|
1550 |
-
this.builder.model.refreshPanelsData();
|
1551 |
-
|
1552 |
-
return false;
|
1553 |
-
},
|
1554 |
-
|
1555 |
-
/**
|
1556 |
-
* The user clicks delete, so trigger deletion on the row model
|
1557 |
-
*/
|
1558 |
-
deleteHandler: function () {
|
1559 |
-
// Trigger a destroy on the model that will happen with a visual indication to the user
|
1560 |
-
this.rowView.visualDestroyModel();
|
1561 |
-
this.closeDialog({silent: true});
|
1562 |
-
|
1563 |
-
return false;
|
1564 |
-
},
|
1565 |
-
|
1566 |
-
/**
|
1567 |
-
* Duplicate this row
|
1568 |
-
*/
|
1569 |
-
duplicateHandler: function () {
|
1570 |
-
this.builder.addHistoryEntry('row_duplicated');
|
1571 |
-
|
1572 |
-
var duplicateRow = this.model.clone(this.builder.model);
|
1573 |
-
|
1574 |
-
this.builder.model.get('rows').add( duplicateRow, {
|
1575 |
-
at: this.builder.model.get('rows').indexOf(this.model) + 1
|
1576 |
-
} );
|
1577 |
-
|
1578 |
-
this.closeDialog({silent: true});
|
1579 |
-
|
1580 |
-
return false;
|
1581 |
-
},
|
1582 |
-
|
1583 |
-
closeHandler: function() {
|
1584 |
-
this.clearCellStylesCache();
|
1585 |
-
if( ! _.isUndefined(this.cellStyles) ) {
|
1586 |
-
this.cellStyles = undefined;
|
1587 |
-
}
|
1588 |
-
},
|
1589 |
-
|
1590 |
-
});
|
1591 |
-
|
1592 |
-
},{}],9:[function(require,module,exports){
|
1593 |
-
var panels = window.panels, $ = jQuery;
|
1594 |
-
var jsWidget = require( '../view/widgets/js-widget' );
|
1595 |
-
|
1596 |
-
module.exports = panels.view.dialog.extend( {
|
1597 |
-
|
1598 |
-
builder: null,
|
1599 |
-
sidebarWidgetTemplate: _.template( panels.helpers.utils.processTemplate( $( '#siteorigin-panels-dialog-widget-sidebar-widget' ).html() ) ),
|
1600 |
-
|
1601 |
-
dialogClass: 'so-panels-dialog-edit-widget',
|
1602 |
-
dialogIcon: 'add-widget',
|
1603 |
-
|
1604 |
-
widgetView: false,
|
1605 |
-
savingWidget: false,
|
1606 |
-
editableLabel: true,
|
1607 |
-
|
1608 |
-
events: {
|
1609 |
-
'click .so-close': 'saveHandler',
|
1610 |
-
'click .so-nav.so-previous': 'navToPrevious',
|
1611 |
-
'click .so-nav.so-next': 'navToNext',
|
1612 |
-
|
1613 |
-
// Action handlers
|
1614 |
-
'click .so-toolbar .so-delete': 'deleteHandler',
|
1615 |
-
'click .so-toolbar .so-duplicate': 'duplicateHandler'
|
1616 |
-
},
|
1617 |
-
|
1618 |
-
initializeDialog: function () {
|
1619 |
-
var thisView = this;
|
1620 |
-
this.listenTo( this.model, 'change:values', this.handleChangeValues );
|
1621 |
-
this.listenTo( this.model, 'destroy', this.remove );
|
1622 |
-
|
1623 |
-
// Refresh panels data after both dialog form components are loaded
|
1624 |
-
this.dialogFormsLoaded = 0;
|
1625 |
-
this.on( 'form_loaded styles_loaded', function () {
|
1626 |
-
this.dialogFormsLoaded ++;
|
1627 |
-
if ( this.dialogFormsLoaded === 2 ) {
|
1628 |
-
thisView.updateModel( {
|
1629 |
-
refreshArgs: {
|
1630 |
-
silent: true
|
1631 |
-
}
|
1632 |
-
} );
|
1633 |
-
}
|
1634 |
-
} );
|
1635 |
-
|
1636 |
-
this.on( 'edit_label', function ( text ) {
|
1637 |
-
// If text is set to default value, just clear it.
|
1638 |
-
if ( text === panelsOptions.widgets[ this.model.get( 'class' ) ][ 'title' ] ) {
|
1639 |
-
text = '';
|
1640 |
-
}
|
1641 |
-
this.model.set( 'label', text );
|
1642 |
-
if ( _.isEmpty( text ) ) {
|
1643 |
-
this.$( '.so-title' ).text( this.model.getWidgetField( 'title' ) );
|
1644 |
-
}
|
1645 |
-
}.bind( this ) );
|
1646 |
-
},
|
1647 |
-
|
1648 |
-
/**
|
1649 |
-
* Render the widget dialog.
|
1650 |
-
*/
|
1651 |
-
render: function () {
|
1652 |
-
// Render the dialog and attach it to the builder interface
|
1653 |
-
this.renderDialog( this.parseDialogContent( $( '#siteorigin-panels-dialog-widget' ).html(), {} ) );
|
1654 |
-
this.loadForm();
|
1655 |
-
|
1656 |
-
var title = this.model.getWidgetField( 'title' );
|
1657 |
-
this.$( '.so-title .widget-name' ).html( title );
|
1658 |
-
this.$( '.so-edit-title' ).val( title );
|
1659 |
-
|
1660 |
-
if( ! this.builder.supports( 'addWidget' ) ) {
|
1661 |
-
this.$( '.so-buttons .so-duplicate' ).remove();
|
1662 |
-
}
|
1663 |
-
if( ! this.builder.supports( 'deleteWidget' ) ) {
|
1664 |
-
this.$( '.so-buttons .so-delete' ).remove();
|
1665 |
-
}
|
1666 |
-
|
1667 |
-
// Now we need to attach the style window
|
1668 |
-
this.styles = new panels.view.styles();
|
1669 |
-
this.styles.model = this.model;
|
1670 |
-
this.styles.render( 'widget', this.builder.config.postId, {
|
1671 |
-
builderType: this.builder.config.builderType,
|
1672 |
-
dialog: this
|
1673 |
-
} );
|
1674 |
-
|
1675 |
-
var $rightSidebar = this.$( '.so-sidebar.so-right-sidebar' );
|
1676 |
-
this.styles.attach( $rightSidebar );
|
1677 |
-
|
1678 |
-
// Handle the loading class
|
1679 |
-
this.styles.on( 'styles_loaded', function ( hasStyles ) {
|
1680 |
-
// If we don't have styles remove the empty sidebar.
|
1681 |
-
if ( ! hasStyles ) {
|
1682 |
-
$rightSidebar.closest( '.so-panels-dialog' ).removeClass( 'so-panels-dialog-has-right-sidebar' );
|
1683 |
-
$rightSidebar.remove();
|
1684 |
-
}
|
1685 |
-
}, this );
|
1686 |
-
},
|
1687 |
-
|
1688 |
-
/**
|
1689 |
-
* Get the previous widget editing dialog by looking at the dom.
|
1690 |
-
* @returns {*}
|
1691 |
-
*/
|
1692 |
-
getPrevDialog: function () {
|
1693 |
-
var widgets = this.builder.$( '.so-cells .cell .so-widget' );
|
1694 |
-
if ( widgets.length <= 1 ) {
|
1695 |
-
return false;
|
1696 |
-
}
|
1697 |
-
var currentIndex = widgets.index( this.widgetView.$el );
|
1698 |
-
|
1699 |
-
if ( currentIndex === 0 ) {
|
1700 |
-
return false;
|
1701 |
-
} else {
|
1702 |
-
var widgetView;
|
1703 |
-
do {
|
1704 |
-
widgetView = widgets.eq( --currentIndex ).data( 'view' );
|
1705 |
-
if ( ! _.isUndefined( widgetView ) && ! widgetView.model.get( 'read_only' ) ) {
|
1706 |
-
return widgetView.getEditDialog();
|
1707 |
-
}
|
1708 |
-
} while( ! _.isUndefined( widgetView ) && currentIndex > 0 );
|
1709 |
-
}
|
1710 |
-
|
1711 |
-
return false;
|
1712 |
-
},
|
1713 |
-
|
1714 |
-
/**
|
1715 |
-
* Get the next widget editing dialog by looking at the dom.
|
1716 |
-
* @returns {*}
|
1717 |
-
*/
|
1718 |
-
getNextDialog: function () {
|
1719 |
-
var widgets = this.builder.$( '.so-cells .cell .so-widget' );
|
1720 |
-
if ( widgets.length <= 1 ) {
|
1721 |
-
return false;
|
1722 |
-
}
|
1723 |
-
|
1724 |
-
var currentIndex = widgets.index( this.widgetView.$el );
|
1725 |
-
|
1726 |
-
if ( currentIndex === widgets.length - 1 ) {
|
1727 |
-
return false;
|
1728 |
-
} else {
|
1729 |
-
var widgetView;
|
1730 |
-
do {
|
1731 |
-
widgetView = widgets.eq( ++currentIndex ).data( 'view' );
|
1732 |
-
if ( ! _.isUndefined( widgetView ) && ! widgetView.model.get( 'read_only' ) ) {
|
1733 |
-
return widgetView.getEditDialog();
|
1734 |
-
}
|
1735 |
-
} while( ! _.isUndefined( widgetView ) );
|
1736 |
-
}
|
1737 |
-
|
1738 |
-
return false;
|
1739 |
-
},
|
1740 |
-
|
1741 |
-
/**
|
1742 |
-
* Load the widget form from the server.
|
1743 |
-
* This is called when rendering the dialog for the first time.
|
1744 |
-
*/
|
1745 |
-
loadForm: function () {
|
1746 |
-
// don't load the form if this dialog hasn't been rendered yet
|
1747 |
-
if ( ! this.$( '> *' ).length ) {
|
1748 |
-
return;
|
1749 |
-
}
|
1750 |
-
|
1751 |
-
this.$( '.so-content' ).addClass( 'so-panels-loading' );
|
1752 |
-
|
1753 |
-
var data = {
|
1754 |
-
'action': 'so_panels_widget_form',
|
1755 |
-
'widget': this.model.get( 'class' ),
|
1756 |
-
'instance': JSON.stringify( this.model.get( 'values' ) ),
|
1757 |
-
'raw': this.model.get( 'raw' )
|
1758 |
-
};
|
1759 |
-
|
1760 |
-
var $soContent = this.$( '.so-content' );
|
1761 |
-
|
1762 |
-
$.post( panelsOptions.ajaxurl, data, null, 'html' )
|
1763 |
-
.done( function ( result ) {
|
1764 |
-
// Add in the CID of the widget model
|
1765 |
-
var html = result.replace( /{\$id}/g, this.model.cid );
|
1766 |
-
|
1767 |
-
// Load this content into the form
|
1768 |
-
$soContent
|
1769 |
-
.removeClass( 'so-panels-loading' )
|
1770 |
-
.html( html );
|
1771 |
-
|
1772 |
-
// Trigger all the necessary events
|
1773 |
-
this.trigger( 'form_loaded', this );
|
1774 |
-
|
1775 |
-
// For legacy compatibility, trigger a panelsopen event
|
1776 |
-
this.$( '.panel-dialog' ).trigger( 'panelsopen' );
|
1777 |
-
|
1778 |
-
// If the main dialog is closed from this point on, save the widget content
|
1779 |
-
this.on( 'close_dialog', this.updateModel, this );
|
1780 |
-
|
1781 |
-
var widgetContent = $soContent.find( '> .widget-content' );
|
1782 |
-
// If there's a widget content wrapper, this is one of the new widgets in WP 4.8 which need some special
|
1783 |
-
// handling in JS.
|
1784 |
-
if ( widgetContent.length > 0 ) {
|
1785 |
-
jsWidget.addWidget( $soContent, this.model.widget_id );
|
1786 |
-
}
|
1787 |
-
|
1788 |
-
}.bind( this ) )
|
1789 |
-
.fail( function ( error ) {
|
1790 |
-
var html;
|
1791 |
-
if ( error && error.responseText ) {
|
1792 |
-
html = error.responseText;
|
1793 |
-
} else {
|
1794 |
-
html = panelsOptions.forms.loadingFailed;
|
1795 |
-
}
|
1796 |
-
|
1797 |
-
$soContent
|
1798 |
-
.removeClass( 'so-panels-loading' )
|
1799 |
-
.html( html );
|
1800 |
-
} );
|
1801 |
-
},
|
1802 |
-
|
1803 |
-
/**
|
1804 |
-
* Save the widget from the form to the model
|
1805 |
-
*/
|
1806 |
-
updateModel: function ( args ) {
|
1807 |
-
args = _.extend( {
|
1808 |
-
refresh: true,
|
1809 |
-
refreshArgs: null
|
1810 |
-
}, args );
|
1811 |
-
|
1812 |
-
// Get the values from the form and assign the new values to the model
|
1813 |
-
this.savingWidget = true;
|
1814 |
-
|
1815 |
-
if ( ! this.model.get( 'missing' ) ) {
|
1816 |
-
// Only get the values for non missing widgets.
|
1817 |
-
var values = this.getFormValues();
|
1818 |
-
if ( _.isUndefined( values.widgets ) ) {
|
1819 |
-
values = {};
|
1820 |
-
} else {
|
1821 |
-
values = values.widgets;
|
1822 |
-
values = values[Object.keys( values )[0]];
|
1823 |
-
}
|
1824 |
-
|
1825 |
-
this.model.setValues( values );
|
1826 |
-
this.model.set( 'raw', true ); // We've saved from the widget form, so this is now raw
|
1827 |
-
}
|
1828 |
-
|
1829 |
-
if ( this.styles.stylesLoaded ) {
|
1830 |
-
// If the styles view has loaded
|
1831 |
-
var style = {};
|
1832 |
-
try {
|
1833 |
-
style = this.getFormValues( '.so-sidebar .so-visual-styles' ).style;
|
1834 |
-
}
|
1835 |
-
catch ( e ) {
|
1836 |
-
}
|
1837 |
-
this.model.set( 'style', style );
|
1838 |
-
}
|
1839 |
-
|
1840 |
-
this.savingWidget = false;
|
1841 |
-
|
1842 |
-
if ( args.refresh ) {
|
1843 |
-
this.builder.model.refreshPanelsData( args.refreshArgs );
|
1844 |
-
}
|
1845 |
-
},
|
1846 |
-
|
1847 |
-
/**
|
1848 |
-
*
|
1849 |
-
*/
|
1850 |
-
handleChangeValues: function () {
|
1851 |
-
if ( ! this.savingWidget ) {
|
1852 |
-
// Reload the form when we've changed the model and we're not currently saving from the form
|
1853 |
-
this.loadForm();
|
1854 |
-
}
|
1855 |
-
},
|
1856 |
-
|
1857 |
-
/**
|
1858 |
-
* Save a history entry for this widget. Called when the dialog is closed.
|
1859 |
-
*/
|
1860 |
-
saveHandler: function () {
|
1861 |
-
this.builder.addHistoryEntry( 'widget_edited' );
|
1862 |
-
this.closeDialog();
|
1863 |
-
},
|
1864 |
-
|
1865 |
-
/**
|
1866 |
-
* When the user clicks delete.
|
1867 |
-
*
|
1868 |
-
* @returns {boolean}
|
1869 |
-
*/
|
1870 |
-
deleteHandler: function () {
|
1871 |
-
this.widgetView.visualDestroyModel();
|
1872 |
-
this.closeDialog( {silent: true} );
|
1873 |
-
this.builder.model.refreshPanelsData();
|
1874 |
-
|
1875 |
-
return false;
|
1876 |
-
},
|
1877 |
-
|
1878 |
-
duplicateHandler: function () {
|
1879 |
-
// Call the widget duplicate handler directly
|
1880 |
-
this.widgetView.duplicateHandler();
|
1881 |
-
|
1882 |
-
this.closeDialog( {silent: true} );
|
1883 |
-
this.builder.model.refreshPanelsData();
|
1884 |
-
|
1885 |
-
return false;
|
1886 |
-
}
|
1887 |
-
|
1888 |
-
} );
|
1889 |
-
|
1890 |
-
},{"../view/widgets/js-widget":31}],10:[function(require,module,exports){
|
1891 |
-
var panels = window.panels, $ = jQuery;
|
1892 |
-
|
1893 |
-
module.exports = panels.view.dialog.extend( {
|
1894 |
-
|
1895 |
-
builder: null,
|
1896 |
-
widgetTemplate: _.template( panels.helpers.utils.processTemplate( $( '#siteorigin-panels-dialog-widgets-widget' ).html() ) ),
|
1897 |
-
filter: {},
|
1898 |
-
|
1899 |
-
dialogClass: 'so-panels-dialog-add-widget',
|
1900 |
-
dialogIcon: 'add-widget',
|
1901 |
-
|
1902 |
-
events: {
|
1903 |
-
'click .so-close': 'closeDialog',
|
1904 |
-
'click .widget-type': 'widgetClickHandler',
|
1905 |
-
'keyup .so-sidebar-search': 'searchHandler'
|
1906 |
-
},
|
1907 |
-
|
1908 |
-
/**
|
1909 |
-
* Initialize the widget adding dialog
|
1910 |
-
*/
|
1911 |
-
initializeDialog: function () {
|
1912 |
-
|
1913 |
-
this.on( 'open_dialog', function () {
|
1914 |
-
this.filter.search = '';
|
1915 |
-
this.filterWidgets( this.filter );
|
1916 |
-
}, this );
|
1917 |
-
|
1918 |
-
this.on( 'open_dialog_complete', function () {
|
1919 |
-
// Clear the search and re-filter the widgets when we open the dialog
|
1920 |
-
this.$( '.so-sidebar-search' ).val( '' ).focus();
|
1921 |
-
this.balanceWidgetHeights();
|
1922 |
-
} );
|
1923 |
-
|
1924 |
-
// We'll implement a custom tab click handler
|
1925 |
-
this.on( 'tab_click', this.tabClickHandler, this );
|
1926 |
-
},
|
1927 |
-
|
1928 |
-
render: function () {
|
1929 |
-
// Render the dialog and attach it to the builder interface
|
1930 |
-
this.renderDialog( this.parseDialogContent( $( '#siteorigin-panels-dialog-widgets' ).html(), {} ) );
|
1931 |
-
|
1932 |
-
// Add all the widgets
|
1933 |
-
_.each( panelsOptions.widgets, function ( widget ) {
|
1934 |
-
var $w = $( this.widgetTemplate( {
|
1935 |
-
title: widget.title,
|
1936 |
-
description: widget.description
|
1937 |
-
} ) );
|
1938 |
-
|
1939 |
-
if ( _.isUndefined( widget.icon ) ) {
|
1940 |
-
widget.icon = 'dashicons dashicons-admin-generic';
|
1941 |
-
}
|
1942 |
-
|
1943 |
-
$( '<span class="widget-icon" />' ).addClass( widget.icon ).prependTo( $w.find( '.widget-type-wrapper' ) );
|
1944 |
-
|
1945 |
-
$w.data( 'class', widget.class ).appendTo( this.$( '.widget-type-list' ) );
|
1946 |
-
}, this );
|
1947 |
-
|
1948 |
-
// Add the sidebar tabs
|
1949 |
-
var tabs = this.$( '.so-sidebar-tabs' );
|
1950 |
-
_.each( panelsOptions.widget_dialog_tabs, function ( tab ) {
|
1951 |
-
$( this.dialogTabTemplate( {'title': tab.title} ) ).data( {
|
1952 |
-
'message': tab.message,
|
1953 |
-
'filter': tab.filter
|
1954 |
-
} ).appendTo( tabs );
|
1955 |
-
}, this );
|
1956 |
-
|
1957 |
-
// We'll be using tabs, so initialize them
|
1958 |
-
this.initTabs();
|
1959 |
-
|
1960 |
-
var thisDialog = this;
|
1961 |
-
$( window ).resize( function () {
|
1962 |
-
thisDialog.balanceWidgetHeights();
|
1963 |
-
} );
|
1964 |
-
},
|
1965 |
-
|
1966 |
-
/**
|
1967 |
-
* Handle a tab being clicked
|
1968 |
-
*/
|
1969 |
-
tabClickHandler: function ( $t ) {
|
1970 |
-
// Get the filter from the tab, and filter the widgets
|
1971 |
-
this.filter = $t.parent().data( 'filter' );
|
1972 |
-
this.filter.search = this.$( '.so-sidebar-search' ).val();
|
1973 |
-
|
1974 |
-
var message = $t.parent().data( 'message' );
|
1975 |
-
if ( _.isEmpty( message ) ) {
|
1976 |
-
message = '';
|
1977 |
-
}
|
1978 |
-
|
1979 |
-
this.$( '.so-toolbar .so-status' ).html( message );
|
1980 |
-
|
1981 |
-
this.filterWidgets( this.filter );
|
1982 |
-
|
1983 |
-
return false;
|
1984 |
-
},
|
1985 |
-
|
1986 |
-
/**
|
1987 |
-
* Handle changes to the search value
|
1988 |
-
*/
|
1989 |
-
searchHandler: function ( e ) {
|
1990 |
-
if( e.which === 13 ) {
|
1991 |
-
var visibleWidgets = this.$( '.widget-type-list .widget-type:visible' );
|
1992 |
-
if( visibleWidgets.length === 1 ) {
|
1993 |
-
visibleWidgets.click();
|
1994 |
-
}
|
1995 |
-
}
|
1996 |
-
else {
|
1997 |
-
this.filter.search = $( e.target ).val().trim();
|
1998 |
-
this.filterWidgets( this.filter );
|
1999 |
-
}
|
2000 |
-
},
|
2001 |
-
|
2002 |
-
/**
|
2003 |
-
* Filter the widgets that we're displaying
|
2004 |
-
* @param filter
|
2005 |
-
*/
|
2006 |
-
filterWidgets: function ( filter ) {
|
2007 |
-
if ( _.isUndefined( filter ) ) {
|
2008 |
-
filter = {};
|
2009 |
-
}
|
2010 |
-
|
2011 |
-
if ( _.isUndefined( filter.groups ) ) {
|
2012 |
-
filter.groups = '';
|
2013 |
-
}
|
2014 |
-
|
2015 |
-
this.$( '.widget-type-list .widget-type' ).each( function () {
|
2016 |