first
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Elementor Preview Styles
|
||||
*/
|
||||
.visual-portfolio-elementor-preview {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
|
||||
iframe {
|
||||
max-width: none;
|
||||
min-height: 20px;
|
||||
}
|
||||
}
|
1071
wp-content/plugins/visual-portfolio/assets/admin/css/style.scss
Normal file
After Width: | Height: | Size: 303 KiB |
After Width: | Height: | Size: 128 KiB |
After Width: | Height: | Size: 235 KiB |
After Width: | Height: | Size: 176 KiB |
After Width: | Height: | Size: 190 KiB |
After Width: | Height: | Size: 170 KiB |
@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 15 15">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #bbbbbb;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<rect id="BR" class="cls-1" y="6" width="7" height="9"/>
|
||||
<rect id="BL" class="cls-1" x="8" y="10" width="7" height="5"/>
|
||||
<rect id="TR" class="cls-1" width="7" height="5"/>
|
||||
<rect id="TL" class="cls-1" x="8" width="7" height="9"/>
|
||||
</svg>
|
After Width: | Height: | Size: 454 B |
@ -0,0 +1,11 @@
|
||||
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="100" height="100" rx="50" fill="currentColor"/>
|
||||
<path d="M57.5311 69.5L70.2439 33H58.4473L47 69.5H57.5311Z" fill="url(#paint0_linear)"/>
|
||||
<path d="M42.7128 69.5L30 33H41.7966L53.2439 69.5H42.7128Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="64.5" y1="33" x2="33" y2="77" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 548 B |
@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 15 15">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #555d66;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<rect id="BR" class="cls-1" y="6" width="7" height="9"/>
|
||||
<rect id="BL" class="cls-1" x="8" y="10" width="7" height="5"/>
|
||||
<rect id="TR" class="cls-1" width="7" height="5"/>
|
||||
<rect id="TL" class="cls-1" x="8" width="7" height="9"/>
|
||||
</svg>
|
After Width: | Height: | Size: 454 B |
After Width: | Height: | Size: 20 KiB |
@ -0,0 +1,11 @@
|
||||
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="100" height="100" rx="50" fill="white"/>
|
||||
<path d="M57.5311 69.5L70.2439 33H58.4473L47 69.5H57.5311Z" fill="url(#paint0_linear)"/>
|
||||
<path d="M42.7128 69.5L30 33H41.7966L53.2439 69.5H42.7128Z" fill="black"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="64.5" y1="33" x2="33" y2="77" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 503 B |
After Width: | Height: | Size: 133 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 65 KiB |
After Width: | Height: | Size: 107 KiB |
@ -0,0 +1,52 @@
|
||||
import $ from 'jquery';
|
||||
|
||||
const { ajaxurl, VPAdminVariables } = window;
|
||||
|
||||
// multiple select with AJAX search
|
||||
$('select[name="vp_general[portfolio_archive_page]"]').select2({
|
||||
ajax: {
|
||||
url: ajaxurl, // AJAX URL is predefined in WordPress admin
|
||||
dataType: 'json',
|
||||
delay: 250, // delay in ms while typing when to perform a AJAX search
|
||||
data(params) {
|
||||
return {
|
||||
q: params.term, // search query
|
||||
selected: this[0].value,
|
||||
nonce: VPAdminVariables.nonce,
|
||||
action: 'vp_get_pages_list', // AJAX action for admin-ajax.php
|
||||
};
|
||||
},
|
||||
processResults(ajaxData) {
|
||||
const options = [];
|
||||
const data = this.$element.select2('data');
|
||||
let alreadyAddedID = false;
|
||||
|
||||
// add selected value.
|
||||
if (data && data[0] && data[0].selected) {
|
||||
alreadyAddedID = Number(data[0].id);
|
||||
options.push({
|
||||
id: alreadyAddedID,
|
||||
text: data[0].text,
|
||||
});
|
||||
}
|
||||
|
||||
// parse new options.
|
||||
if (ajaxData) {
|
||||
// ajaxData is the array of arrays, and each of them contains ID and the Label of the option
|
||||
$.each(ajaxData, (index, itemData) => {
|
||||
if (!alreadyAddedID || alreadyAddedID !== itemData[0]) {
|
||||
options.push({
|
||||
id: itemData[0],
|
||||
text: itemData[1],
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
results: options,
|
||||
};
|
||||
},
|
||||
cache: true,
|
||||
},
|
||||
});
|
@ -0,0 +1,24 @@
|
||||
import $ from 'jquery';
|
||||
|
||||
const { ajaxurl, VPAskReviewNotice } = window;
|
||||
const $body = $('body');
|
||||
|
||||
$body.on('click', '.vpf-review-plugin-notice-dismiss', function (e) {
|
||||
const $this = $(this);
|
||||
const type = $this.attr('data-vpf-review-action');
|
||||
|
||||
// Don't prevent click on Yes link, as it is URL for rate.
|
||||
if (type !== 'yes') {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
// Hide notice.
|
||||
$this.closest('.notice').slideUp('slow');
|
||||
|
||||
// Save user answer in DB.
|
||||
$.post(ajaxurl, {
|
||||
action: 'vpf_dismiss_ask_review_notice',
|
||||
type,
|
||||
nonce: VPAskReviewNotice.nonce,
|
||||
});
|
||||
});
|
@ -0,0 +1,84 @@
|
||||
import $ from 'jquery';
|
||||
import rafSchd from 'raf-schd';
|
||||
import { throttle } from 'throttle-debounce';
|
||||
|
||||
const { elementorFrontend, VPAdminElementorVariables: variables } = window;
|
||||
const $wnd = $(window);
|
||||
|
||||
$wnd.on('elementor/frontend/init', ($data) => {
|
||||
if (!variables) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { target: elementorWindow } = $data;
|
||||
|
||||
// add fake iframe width, so @media styles will work fine.
|
||||
function maybeResizePreviews() {
|
||||
const elementorWidth = elementorWindow
|
||||
.jQuery(elementorWindow.document)
|
||||
.width();
|
||||
|
||||
elementorWindow.jQuery
|
||||
.find('.visual-portfolio-elementor-preview iframe')
|
||||
.forEach((item) => {
|
||||
const $this = $(item);
|
||||
const parentWidth = $this.parent().width();
|
||||
|
||||
$this.css({
|
||||
width: elementorWidth,
|
||||
});
|
||||
|
||||
if (item.iFrameResizer) {
|
||||
item.iFrameResizer.sendMessage({
|
||||
name: 'resize',
|
||||
width: parentWidth,
|
||||
});
|
||||
item.iFrameResizer.resize();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// window resize.
|
||||
$wnd.on('resize', throttle(300, rafSchd(maybeResizePreviews)));
|
||||
|
||||
// added/changed widget.
|
||||
elementorFrontend.hooks.addAction(
|
||||
'frontend/element_ready/visual-portfolio.default',
|
||||
($scope) => {
|
||||
const $block = $($scope).find(
|
||||
'.visual-portfolio-elementor-preview'
|
||||
);
|
||||
const $frame = $block.find('iframe');
|
||||
const id = $block.attr('data-id');
|
||||
const iframeURL = `${
|
||||
variables.preview_url +
|
||||
(variables.preview_url.split('?')[1] ? '&' : '?')
|
||||
}vp_preview_frame=true&vp_preview_type=elementor&vp_preview_frame_id=${id}&vp_preview_nonce=${
|
||||
variables.nonce
|
||||
}`;
|
||||
|
||||
$frame.attr('src', iframeURL);
|
||||
|
||||
// resize iframe
|
||||
if ($.fn.iFrameResize) {
|
||||
$frame.iFrameResize({
|
||||
onInit() {
|
||||
maybeResizePreviews();
|
||||
},
|
||||
onMessage({ message }) {
|
||||
// select current block on click message.
|
||||
if (message === 'clicked') {
|
||||
// Select current widget to display settings.
|
||||
$frame
|
||||
.closest('.elementor-element')
|
||||
.find('.elementor-editor-element-edit')
|
||||
.click();
|
||||
|
||||
window.focus();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
@ -0,0 +1,48 @@
|
||||
const { tinymce, VPTinyMCEData } = window;
|
||||
|
||||
if (typeof VPTinyMCEData !== 'undefined' && VPTinyMCEData.layouts.length) {
|
||||
const options = [
|
||||
{
|
||||
text: '',
|
||||
value: '',
|
||||
},
|
||||
];
|
||||
|
||||
Object.keys(VPTinyMCEData.layouts).forEach((k) => {
|
||||
options.push({
|
||||
text: VPTinyMCEData.layouts[k].title,
|
||||
value: VPTinyMCEData.layouts[k].id,
|
||||
});
|
||||
});
|
||||
|
||||
tinymce.create('tinymce.plugins.visual_portfolio', {
|
||||
init(editor) {
|
||||
editor.addButton('visual_portfolio', {
|
||||
type: 'listbox',
|
||||
title: VPTinyMCEData.plugin_name,
|
||||
icon: 'visual-portfolio',
|
||||
classes: 'visual-portfolio-btn',
|
||||
onclick() {
|
||||
if (this.menu) {
|
||||
this.menu.$el.find('.mce-first').hide();
|
||||
}
|
||||
},
|
||||
onselect() {
|
||||
if (this.value()) {
|
||||
editor.insertContent(
|
||||
`[visual_portfolio id="${this.value()}"]`
|
||||
);
|
||||
}
|
||||
this.value('');
|
||||
},
|
||||
values: options,
|
||||
value: '',
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
tinymce.PluginManager.add(
|
||||
'visual_portfolio',
|
||||
tinymce.plugins.visual_portfolio
|
||||
);
|
||||
}
|
106
wp-content/plugins/visual-portfolio/assets/admin/js/script.js
Normal file
@ -0,0 +1,106 @@
|
||||
import $ from 'jquery';
|
||||
import rafSchd from 'raf-schd';
|
||||
|
||||
import { debounce } from '@wordpress/compose';
|
||||
|
||||
const { ajaxurl, VPAdminVariables } = window;
|
||||
const $body = $('body');
|
||||
|
||||
// select shortcode text in input
|
||||
$body.on(
|
||||
'focus',
|
||||
'[name="vp_list_shortcode"], [name="vp_filter_shortcode"], [name="vp_sort_shortcode"]',
|
||||
function () {
|
||||
this.select();
|
||||
}
|
||||
);
|
||||
$body.on('click', '.vp-onclick-selection', function () {
|
||||
// eslint-disable-next-line @wordpress/no-global-get-selection
|
||||
window.getSelection().selectAllChildren(this);
|
||||
});
|
||||
// fix the problem with Gutenberg shortcode transform (allowed only plain text pasted).
|
||||
$body.on('copy cut', '.vp-onclick-selection', (e) => {
|
||||
// eslint-disable-next-line @wordpress/no-global-get-selection
|
||||
const copyText = window
|
||||
.getSelection()
|
||||
.toString()
|
||||
.replace(/[\n\r]+/g, '');
|
||||
|
||||
e.originalEvent.clipboardData.setData('text/plain', copyText);
|
||||
e.originalEvent.preventDefault();
|
||||
});
|
||||
|
||||
// Post format metabox show/hide
|
||||
const $videoMetabox = $('#vp_format_video');
|
||||
const $videoFormatCheckbox = $('#post-format-video');
|
||||
let isVideoFormat = null;
|
||||
|
||||
function toggleVideoMetabox(show) {
|
||||
if (isVideoFormat === null || isVideoFormat !== show) {
|
||||
isVideoFormat = show;
|
||||
$videoMetabox[show ? 'show' : 'hide']();
|
||||
}
|
||||
}
|
||||
|
||||
if ($videoMetabox.length) {
|
||||
if ($videoFormatCheckbox.length) {
|
||||
toggleVideoMetabox($videoFormatCheckbox.is(':checked'));
|
||||
|
||||
$body.on('change', '[name=post_format]', () => {
|
||||
toggleVideoMetabox($videoFormatCheckbox.is(':checked'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let oembedAjax = null;
|
||||
let runAjaxVideoOembed = function ($this) {
|
||||
oembedAjax = $.ajax({
|
||||
url: ajaxurl,
|
||||
method: 'POST',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
action: 'vp_find_oembed',
|
||||
q: $this.val(),
|
||||
nonce: VPAdminVariables.nonce,
|
||||
},
|
||||
complete(data) {
|
||||
const json = data.responseJSON;
|
||||
if (json && typeof json.html !== 'undefined') {
|
||||
$this.next('.vp-oembed-preview').html(json.html);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
runAjaxVideoOembed = debounce(300, rafSchd(runAjaxVideoOembed));
|
||||
|
||||
$body.on('change input', '.vp-input[name="_vp_format_video_url"]', function () {
|
||||
if (oembedAjax !== null) {
|
||||
oembedAjax.abort();
|
||||
}
|
||||
|
||||
const $this = $(this);
|
||||
$this.next('.vp-oembed-preview').html('');
|
||||
|
||||
runAjaxVideoOembed($this);
|
||||
});
|
||||
|
||||
/**
|
||||
* When attempting to disable registration of portfolio post type,
|
||||
* We inform the user of the possible consequences and provide them with the opportunity to cancel this operation.
|
||||
*/
|
||||
$body.on(
|
||||
'change',
|
||||
"input[name='vp_general[register_portfolio_post_type]']",
|
||||
function () {
|
||||
// Does some stuff and logs the event to the console
|
||||
if (!$(this).is(':checked')) {
|
||||
// eslint-disable-next-line no-restricted-globals, no-alert, no-undef
|
||||
const confirmation = confirm(
|
||||
"Are you sure you want to turn off the Portfolio custom post type and related taxonomies? Make sure you don't use this post type on your site, otherwise you might see errors on the frontend."
|
||||
);
|
||||
if (!confirmation) {
|
||||
$(this).prop('checked', true);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
@ -0,0 +1,25 @@
|
||||
import $ from 'jquery';
|
||||
|
||||
const { vc } = window;
|
||||
|
||||
$(() => {
|
||||
// shortcode frontend editor
|
||||
if (typeof vc !== 'undefined') {
|
||||
// on shortcode add and update events
|
||||
vc.events.on('shortcodes:add shortcodeView:updated', (e) => {
|
||||
if (e.settings.base !== 'visual_portfolio') {
|
||||
return;
|
||||
}
|
||||
|
||||
const wnd = vc.$frame[0].contentWindow;
|
||||
const jQframe = wnd ? wnd.jQuery : false;
|
||||
|
||||
if (jQframe) {
|
||||
const $vp = jQframe(e.view.el).children('.vp-portfolio');
|
||||
if ($vp.length && typeof $vp.vpf !== 'undefined') {
|
||||
$vp.vpf();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|