Skip to content

Commit

Permalink
Merge & feature toggle
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelthq authored and konutis committed May 20, 2019
1 parent d06e6c2 commit ca8d1ea
Show file tree
Hide file tree
Showing 13 changed files with 438 additions and 165 deletions.
39 changes: 28 additions & 11 deletions elements/singleImage/singleImage/ResizeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,27 @@ protected function parseImage($matches)
$src = $matchesUrl[1];
}

preg_match('(data-height=["|\']([0-9]{0,4})["|\'])', $matches[1], $matchesUrl);
if (isset($matchesUrl[1])) {
$height = $matchesUrl[1];
preg_match('(data-height=["|\']([0-9]{0,4})["|\'])', $matches[1], $matchesHeight);
if (isset($matchesHeight[1])) {
$height = $matchesHeight[1];
}

preg_match('(data-width=["|\']([0-9]{0,4})["|\'])', $matches[1], $matchesUrl);
if (isset($matchesUrl[1])) {
$width = $matchesUrl[1];
preg_match('(data-width=["|\']([0-9]{0,4})["|\'])', $matches[1], $matchesWidth);
if (isset($matchesWidth[1])) {
$width = $matchesWidth[1];
}

$dynamic = false;
if (vcvenv('VCV_JS_FT_DYNAMIC_FIELDS')) {
// TODO: Change key featured to more specific like featured_image
$isMatches = preg_match('(dynamic="featured")', $matches[1], $matchesDynamic);
if ($isMatches) {
$dynamic = 'featured';
}
}

if (isset($src) && isset($width) && isset($height)) {
return $this->generateImage($matches, $src, $width, $height);
return $this->generateImage($matches, $src, $width, $height, $dynamic);
}
}

Expand Down Expand Up @@ -89,12 +98,14 @@ protected function getImageData($url)
/**
* @param $content
* @param $src
* @param $width
* @param $height
* @param bool $width
* @param bool $height
*
* @param bool $dynamic
*
* @return string
*/
protected function generateImage($content, $src, $width = false, $height = false)
protected function generateImage($content, $src, $width = false, $height = false, $dynamic = false)
{
$imageData = $this->getImageData($src);
$image = wp_get_image_editor($imageData['path']);
Expand All @@ -111,11 +122,17 @@ protected function generateImage($content, $src, $width = false, $height = false
}
}

$newSrc = 'src="' . set_url_scheme($src) . '"';
$newSrc = ' src="' . set_url_scheme($src) . '"';

$attributes = preg_replace('(\ssrc=["|\'](.*?)["|\'])', $newSrc, $content[1]);
$attributes = preg_replace('(data-default-image=["|\'](true|false)["|\'])', '', $attributes);

if ($dynamic) {
return '<!-- wp:vcv-gutenberg-blocks/dynamic-field-block ' . json_encode(
['type' => 'post', 'value' => 'featured', 'atts' => urlencode($attributes)]
) . ' -->';
}

return '<img ' . $attributes . '/>';
}
}
147 changes: 33 additions & 114 deletions elements/singleImage/singleImage/component.js
Original file line number Diff line number Diff line change
@@ -1,87 +1,12 @@
import React from 'react'
import vcCake from 'vc-cake'
import { getService } from 'vc-cake'

const vcvAPI = vcCake.getService('api')
const renderProcessor = vcCake.getService('renderProcessor')
const vcvAPI = getService('api')
const renderProcessor = getService('renderProcessor')

export default class SingleImageElement extends vcvAPI.elementComponent {
promise = null

static drawImageProp (ctx, img, x, y, w, h, offsetX, offsetY) {
if (arguments.length === 2) {
x = y = 0
w = ctx.canvas.width
h = ctx.canvas.height
}

// default offset is center
offsetX = typeof offsetX === 'number' ? offsetX : 0.5
offsetY = typeof offsetY === 'number' ? offsetY : 0.5

// keep bounds [0.0, 1.0]
if (offsetX < 0) {
offsetX = 0
}
if (offsetY < 0) {
offsetY = 0
}
if (offsetX > 1) {
offsetX = 1
}
if (offsetY > 1) {
offsetY = 1
}

let iw = img.width
let ih = img.height
let r = Math.min(w / iw, h / ih)
let nw = iw * r // new prop. width
let nh = ih * r // new prop. height
let cx
let cy
let cw
let ch
let ar = 1

// decide which gap to fill
if (Math.round(nw) < w) {
ar = w / nw
}
if (Math.round(nh) < h) {
ar = h / nh
}

nw *= ar
nh *= ar

// calc source rectangle
cw = iw / (nw / w)
ch = ih / (nh / h)

cx = (iw - cw) * offsetX
cy = (ih - ch) * offsetY

// make sure source rectangle is valid
if (cx < 0) {
cx = 0
}
if (cy < 0) {
cy = 0
}
if (cw > iw) {
cw = iw
}
if (ch > ih) {
ch = ih
}

// make canvas high quality
ctx.imageSmoothingQuality = 'high'

// fill image in dest. rectangle
ctx.drawImage(img, cx, cy, cw, ch, x, y, w, h)
}

static image = null

constructor (props) {
Expand Down Expand Up @@ -113,8 +38,14 @@ export default class SingleImageElement extends vcvAPI.elementComponent {
SingleImageElement.image && SingleImageElement.image.removeEventListener('error', this.setError)
}

componentWillReceiveProps (nextProps) {
this.setImage(nextProps)
componentDidUpdate (prevProps, prevState) {
if (prevProps.atts.image !== this.props.atts.image) {
this.setImage(this.props)
} else if (prevProps.atts.size !== this.props.atts.size) {
this.resetImageSizeState()
} else if (prevProps.atts.shape !== this.props.atts.shape) {
this.resetImageSizeState()
}
}

parseSize (size, isRound, naturalWidth, naturalHeight) {
Expand Down Expand Up @@ -223,7 +154,6 @@ export default class SingleImageElement extends vcvAPI.elementComponent {
} else {
this.setError()
}

if (!imgSrc) {
this.setState({
imgElement: null,
Expand All @@ -240,7 +170,7 @@ export default class SingleImageElement extends vcvAPI.elementComponent {
const sizes = this.getSizes(this.props.atts, img)

this.setState({
imgElement: e.currentTarget,
imgElement: img,
parsedWidth: sizes.width,
parsedHeight: sizes.height,
naturalWidth: img.width,
Expand All @@ -250,48 +180,38 @@ export default class SingleImageElement extends vcvAPI.elementComponent {
})
}

setError () {
this.resolve && this.resolve(false)
resetImageSizeState () {
const sizes = this.getSizes(this.props.atts, this.state.imgElement)
this.setState({
parsedWidth: sizes.width,
parsedHeight: sizes.height
})
}

resizeImage () {
const { imgElement, parsedWidth, parsedHeight, naturalWidth, naturalHeight } = this.state

if (!this.canvas) {
return
}

const ctx = this.canvas.getContext('2d')

if (!imgElement) {
ctx.clearRect(0, 0, parsedWidth, parsedHeight)
return
}

this.canvas.width = parsedWidth
this.canvas.height = parsedHeight
this.canvas.naturalWidth = naturalWidth
this.canvas.naturalHeight = naturalHeight

SingleImageElement.drawImageProp(ctx, imgElement, 0, 0, parsedWidth, parsedHeight, 0.5, 0.5)
setError () {
this.resolve && this.resolve(false)
}

getImageShortcode (options) {
const { props, classes, isDefaultImage, src } = options
const { props, classes, isDefaultImage, src, isDynamicFeaturedImage } = options
let shortcode = `[vcvSingleImage class="${classes}" data-width="${this.state.parsedWidth || 0}" data-height="${this.state.parsedHeight || 0}" src="${src}" data-img-src="${props[ 'data-img-src' ]}" alt="${props.alt}" title="${props.title}"`

if (isDefaultImage) {
shortcode += ' data-default-image="true"'
}

if (isDynamicFeaturedImage) {
shortcode += ` dynamic="featured"`
}

shortcode += ']'

return shortcode
}

render () {
let { id, atts, editor } = this.props
let { image, shape, clickableOptions, showCaption, customClass, size, alignment, metaCustomId } = atts
let { shape, clickableOptions, showCaption, customClass, size, alignment, metaCustomId, image } = atts
let containerClasses = 'vce-single-image-container'
let wrapperClasses = 'vce vce-single-image-wrapper'
let classes = 'vce-single-image-inner'
Expand Down Expand Up @@ -360,8 +280,6 @@ export default class SingleImageElement extends vcvAPI.elementComponent {
classes += ' vce-single-image--border-round'
}

customProps.key = `customProps:${id}-${imgSrc}-${clickableOptions}-${shape}-${size}`

if (metaCustomId) {
containerProps.id = metaCustomId
}
Expand All @@ -383,32 +301,33 @@ export default class SingleImageElement extends vcvAPI.elementComponent {
}

let imgElement = ''
const isDynamic = typeof image === 'string' && image.indexOf('<!-- wp') !== -1 && image.indexOf('featured') > -1
const shortcodeOptions = {
props: customImageProps,
classes: imageClasses,
isDefaultImage: !(image && image.id),
src: imgSrc
src: imgSrc,
isDynamicFeaturedImage: isDynamic
}

if (imgSrc) {
imgElement = (
<span className={`${imageClasses} vcvhelper`}
{...customImageProps}
data-vcvs-html={this.getImageShortcode(shortcodeOptions)}>
<canvas ref={(canvas) => { this.canvas = canvas }} />
data-vcvs-html={this.getImageShortcode(shortcodeOptions)}
style={{ paddingBottom: `${(this.state.parsedHeight / this.state.parsedWidth) * 100}%`, width: this.state.parsedWidth }}>
<img src={imgSrc} />
</span>
)
}

// Set original image if not resized
if (size === 'full' && shape !== 'round') {
if (size === 'full' && shape !== 'round' && !isDynamic) {
imgElement = (
<img className={imageClasses} src={imgSrc} {...customImageProps} />
)
}

this.resizeImage()

return <div className={containerClasses} {...editor} {...containerProps}>
<div className={wrapperClasses} {...wrapperProps} id={'el-' + id} {...doAll}>
<figure>
Expand Down
13 changes: 11 additions & 2 deletions elements/singleImage/singleImage/editor.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@
min-height: 1em;
}

.vce-single-image canvas {
.vce-single-image {
max-width: 100%;
vertical-align: top;
}

.vce-single-image img {
object-fit: cover;
position: absolute;
left: 0;
right: 0;
top: 0;
width: 100%;
height: 100%;
}

.vce-single-image.vcvhelper {
Expand Down
4 changes: 4 additions & 0 deletions env.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,7 @@
if (!VcvEnv::has('VCV_ENV_PLUGIN_UPDATE_PACKAGE_URL')) {
VcvEnv::set('VCV_ENV_PLUGIN_UPDATE_PACKAGE_URL', defined('VCV_ENV_PLUGIN_UPDATE_PACKAGE_URL') ? constant('VCV_ENV_PLUGIN_UPDATE_PACKAGE_URL'): 'http://updates.visualcomposer.io/visual-composer-website-builder/visualcomposer.zip');
}

if (!VcvEnv::has('VCV_JS_FT_DYNAMIC_FIELDS')) {
VcvEnv::set('VCV_JS_FT_DYNAMIC_FIELDS', false);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const elementsStorage = vcCake.getStorage('elements')
const wordpressDataStorage = vcCake.getStorage('wordpressData')
const shortcodesAssetsStorage = vcCake.getStorage('shortcodeAssets')
const workspaceStorage = vcCake.getStorage('workspace')
const { getShortcodesRegexp } = vcCake.getService('utils')

export default class ContentEditableComponent extends React.Component {
static spinnerHTML = '<span class="vcv-ui-content-editable-helper-loader vcv-ui-wp-spinner"></span>'
Expand Down Expand Up @@ -289,10 +290,6 @@ export default class ContentEditableComponent extends React.Component {
}
}

getShortcodesRegexp () {
return new RegExp('\\[(\\[?)([\\w|-]+\\b)(?![\\w-])([^\\]\\/]*(?:\\/(?!\\])[^\\]\\/]*)*?)(?:(\\/)\\]|\\](?:([^\\[]*(?:\\[(?!\\/\\2\\])[^\\[]*)*)(\\[\\/\\2\\]))?)(\\]?)')
}

editorSetup (options) {
let editorSettings = {
target: this.ref,
Expand Down Expand Up @@ -393,7 +390,7 @@ export default class ContentEditableComponent extends React.Component {
}

updateHtmlWithServer (content) {
if (content && (content.match(this.getShortcodesRegexp()) || content.match(/https?:\/\//))) {
if (content && (content.match(getShortcodesRegexp()) || content.match(/https?:\/\//) || content.indexOf('<!-- wp') !== -1)) {
this.ref && (this.ref.innerHTML = ContentEditableComponent.spinnerHTML)
dataProcessor.appServerRequest({
'vcv-action': 'elements:ajaxShortcode:adminNonce',
Expand Down
Loading

0 comments on commit ca8d1ea

Please sign in to comment.