mirror of https://github.com/artf/grapesjs.git
4 changed files with 167 additions and 159 deletions
@ -1,152 +1,170 @@ |
|||||
import { isUndefined, isString } from 'underscore'; |
import { isUndefined, isString } from 'underscore'; |
||||
|
|
||||
module.exports = require('backbone').Model.extend({ |
const Property = require('backbone').Model.extend( |
||||
defaults: { |
{ |
||||
name: '', |
defaults: { |
||||
property: '', |
name: '', |
||||
type: '', |
property: '', |
||||
defaults: '', |
type: '', |
||||
info: '', |
defaults: '', |
||||
value: '', |
info: '', |
||||
icon: '', |
value: '', |
||||
functionName: '', |
icon: '', |
||||
status: '', |
functionName: '', |
||||
visible: true, |
status: '', |
||||
fixedValues: ['initial', 'inherit'], |
visible: true, |
||||
|
fixedValues: ['initial', 'inherit'], |
||||
// If true to the value will be added '!important'
|
|
||||
important: 0, |
// If true to the value will be added '!important'
|
||||
|
important: 0, |
||||
// If true, will be hidden by default and will show up only for targets
|
|
||||
// which require this property (via `stylable-require`)
|
// If true, will be hidden by default and will show up only for targets
|
||||
// Use case:
|
// which require this property (via `stylable-require`)
|
||||
// you can add all SVG CSS properties with toRequire as true
|
// Use case:
|
||||
// and then require them on SVG Components
|
// you can add all SVG CSS properties with toRequire as true
|
||||
toRequire: 0 |
// and then require them on SVG Components
|
||||
}, |
toRequire: 0 |
||||
|
}, |
||||
initialize(props = {}, opts = {}) { |
|
||||
var name = this.get('name'); |
initialize(props = {}, opts = {}) { |
||||
var prop = this.get('property'); |
var name = this.get('name'); |
||||
|
var prop = this.get('property'); |
||||
if (!name) { |
|
||||
this.set( |
if (!name) { |
||||
'name', |
this.set( |
||||
prop.charAt(0).toUpperCase() + prop.slice(1).replace(/-/g, ' ') |
'name', |
||||
); |
prop.charAt(0).toUpperCase() + prop.slice(1).replace(/-/g, ' ') |
||||
} |
); |
||||
|
} |
||||
!opts.skipInit && this.init(props, opts); |
Property.callInit(this, props, opts); |
||||
}, |
}, |
||||
|
|
||||
init() {}, |
init() {}, |
||||
|
|
||||
/** |
/** |
||||
* Clear the value |
* Clear the value |
||||
* @return {this} |
* @return {this} |
||||
*/ |
*/ |
||||
clearValue(opts = {}) { |
clearValue(opts = {}) { |
||||
this.set({ value: undefined }, opts); |
this.set({ value: undefined }, opts); |
||||
return this; |
return this; |
||||
}, |
}, |
||||
|
|
||||
/** |
/** |
||||
* Update value |
* Update value |
||||
* @param {any} value |
* @param {any} value |
||||
* @param {Boolen} [complete=true] Indicates if it's a final state |
* @param {Boolen} [complete=true] Indicates if it's a final state |
||||
* @param {Object} [opts={}] Options |
* @param {Object} [opts={}] Options |
||||
*/ |
*/ |
||||
setValue(value, complete = 1, opts = {}) { |
setValue(value, complete = 1, opts = {}) { |
||||
const parsed = this.parseValue(value); |
const parsed = this.parseValue(value); |
||||
this.set(parsed, { ...opts, avoidStore: 1 }); |
this.set(parsed, { ...opts, avoidStore: 1 }); |
||||
|
|
||||
// It's important to set an empty value, otherwise the
|
// It's important to set an empty value, otherwise the
|
||||
// UndoManager won't see the change
|
// UndoManager won't see the change
|
||||
if (complete) { |
if (complete) { |
||||
this.set('value', '', opts); |
this.set('value', '', opts); |
||||
this.set(parsed, opts); |
this.set(parsed, opts); |
||||
} |
} |
||||
}, |
}, |
||||
|
|
||||
/** |
/** |
||||
* Like `setValue` but, in addition, prevents the update of the input element |
* Like `setValue` but, in addition, prevents the update of the input element |
||||
* as the changes should come from the input itself. |
* as the changes should come from the input itself. |
||||
* This method is useful with the definition of custom properties |
* This method is useful with the definition of custom properties |
||||
* @param {any} value |
* @param {any} value |
||||
* @param {Boolen} [complete=true] Indicates if it's a final state |
* @param {Boolen} [complete=true] Indicates if it's a final state |
||||
* @param {Object} [opts={}] Options |
* @param {Object} [opts={}] Options |
||||
*/ |
*/ |
||||
setValueFromInput(value, complete, opts = {}) { |
setValueFromInput(value, complete, opts = {}) { |
||||
this.setValue(value, complete, { ...opts, fromInput: 1 }); |
this.setValue(value, complete, { ...opts, fromInput: 1 }); |
||||
}, |
}, |
||||
|
|
||||
/** |
/** |
||||
* Parse a raw value, generally fetched from the target, for this property |
* Parse a raw value, generally fetched from the target, for this property |
||||
* @param {string} value Raw value string |
* @param {string} value Raw value string |
||||
* @return {Object} |
* @return {Object} |
||||
* @example |
* @example |
||||
* // example with an Input type
|
* // example with an Input type
|
||||
* prop.parseValue('translateX(10deg)'); |
* prop.parseValue('translateX(10deg)'); |
||||
* // -> { value: 10, unit: 'deg', functionName: 'translateX' }
|
* // -> { value: 10, unit: 'deg', functionName: 'translateX' }
|
||||
* |
* |
||||
*/ |
*/ |
||||
parseValue(value) { |
parseValue(value) { |
||||
const result = { value }; |
const result = { value }; |
||||
const imp = '!important'; |
const imp = '!important'; |
||||
|
|
||||
if (isString(value) && value.indexOf(imp) !== -1) { |
if (isString(value) && value.indexOf(imp) !== -1) { |
||||
result.value = value.replace(imp, '').trim(); |
result.value = value.replace(imp, '').trim(); |
||||
result.important = 1; |
result.important = 1; |
||||
} |
} |
||||
|
|
||||
if (!this.get('functionName')) { |
if (!this.get('functionName')) { |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
const args = []; |
||||
|
let valueStr = `${result.value}`; |
||||
|
let start = valueStr.indexOf('(') + 1; |
||||
|
let end = valueStr.lastIndexOf(')'); |
||||
|
args.push(start); |
||||
|
|
||||
|
// Will try even if the last closing parentheses is not found
|
||||
|
if (end >= 0) { |
||||
|
args.push(end); |
||||
|
} |
||||
|
|
||||
|
result.value = String.prototype.substring.apply(valueStr, args); |
||||
return result; |
return result; |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* Get the default value |
||||
|
* @return {string} |
||||
|
* @private |
||||
|
*/ |
||||
|
getDefaultValue() { |
||||
|
return this.get('defaults'); |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* Get a complete value of the property. |
||||
|
* This probably will replace the getValue when all |
||||
|
* properties models will be splitted |
||||
|
* @param {string} val Custom value to replace the one on the model |
||||
|
* @return {string} |
||||
|
* @private |
||||
|
*/ |
||||
|
getFullValue(val) { |
||||
|
const fn = this.get('functionName'); |
||||
|
let value = isUndefined(val) ? this.get('value') : val; |
||||
|
|
||||
|
if (fn && !isUndefined(value)) { |
||||
|
value = `${fn}(${value})`; |
||||
|
} |
||||
|
|
||||
|
if (this.get('important')) { |
||||
|
value = `${value} !important`; |
||||
|
} |
||||
|
|
||||
|
return value || ''; |
||||
} |
} |
||||
|
|
||||
const args = []; |
|
||||
let valueStr = `${result.value}`; |
|
||||
let start = valueStr.indexOf('(') + 1; |
|
||||
let end = valueStr.lastIndexOf(')'); |
|
||||
args.push(start); |
|
||||
|
|
||||
// Will try even if the last closing parentheses is not found
|
|
||||
if (end >= 0) { |
|
||||
args.push(end); |
|
||||
} |
|
||||
|
|
||||
result.value = String.prototype.substring.apply(valueStr, args); |
|
||||
return result; |
|
||||
}, |
}, |
||||
|
{ |
||||
/** |
callParentInit(property, ctx, props, opts = {}) { |
||||
* Get the default value |
property.prototype.initialize.apply(ctx, [ |
||||
* @return {string} |
props, |
||||
* @private |
{ |
||||
*/ |
...opts, |
||||
getDefaultValue() { |
skipInit: 1 |
||||
return this.get('defaults'); |
} |
||||
}, |
]); |
||||
|
}, |
||||
/** |
|
||||
* Get a complete value of the property. |
callInit(context, props, opts = {}) { |
||||
* This probably will replace the getValue when all |
!opts.skipInit && context.init(props, opts); |
||||
* properties models will be splitted |
|
||||
* @param {string} val Custom value to replace the one on the model |
|
||||
* @return {string} |
|
||||
* @private |
|
||||
*/ |
|
||||
getFullValue(val) { |
|
||||
const fn = this.get('functionName'); |
|
||||
let value = isUndefined(val) ? this.get('value') : val; |
|
||||
|
|
||||
if (fn && !isUndefined(value)) { |
|
||||
value = `${fn}(${value})`; |
|
||||
} |
} |
||||
|
|
||||
if (this.get('important')) { |
|
||||
value = `${value} !important`; |
|
||||
} |
|
||||
|
|
||||
return value || ''; |
|
||||
} |
} |
||||
}); |
); |
||||
|
|
||||
|
module.exports = Property; |
||||
|
|||||
Loading…
Reference in new issue