|
|
@ -2,9 +2,20 @@ import { isArray, isString, keys } from 'underscore'; |
|
|
import { Model, ObjectAny, ObjectHash, SetOptions } from '../../common'; |
|
|
import { Model, ObjectAny, ObjectHash, SetOptions } from '../../common'; |
|
|
import ParserHtml from '../../parser/model/ParserHtml'; |
|
|
import ParserHtml from '../../parser/model/ParserHtml'; |
|
|
import Selectors from '../../selector_manager/model/Selectors'; |
|
|
import Selectors from '../../selector_manager/model/Selectors'; |
|
|
import { shallowDiff } from '../../utils/mixins'; |
|
|
import { shallowDiff, get, stringToPath } from '../../utils/mixins'; |
|
|
|
|
|
import EditorModel from '../../editor/model/Editor'; |
|
|
export type StyleProps = Record<string, string | string[]>; |
|
|
import StyleDataVariable from '../../data_sources/model/StyleDataVariable'; |
|
|
|
|
|
|
|
|
|
|
|
export type StyleProps = Record< |
|
|
|
|
|
string, |
|
|
|
|
|
| string |
|
|
|
|
|
| string[] |
|
|
|
|
|
| { |
|
|
|
|
|
type: 'data-variable'; |
|
|
|
|
|
value: string; |
|
|
|
|
|
path: string; |
|
|
|
|
|
} |
|
|
|
|
|
>; |
|
|
|
|
|
|
|
|
export type UpdateStyleOptions = SetOptions & { |
|
|
export type UpdateStyleOptions = SetOptions & { |
|
|
partial?: boolean; |
|
|
partial?: boolean; |
|
|
@ -20,6 +31,8 @@ export const getLastStyleValue = (value: string | string[]) => { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
export default class StyleableModel<T extends ObjectHash = any> extends Model<T> { |
|
|
export default class StyleableModel<T extends ObjectHash = any> extends Model<T> { |
|
|
|
|
|
em?: EditorModel; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Forward style string to `parseStyle` to be parse to an object |
|
|
* Forward style string to `parseStyle` to be parse to an object |
|
|
* @param {string} str |
|
|
* @param {string} str |
|
|
@ -46,6 +59,11 @@ export default class StyleableModel<T extends ObjectHash = any> extends Model<T> |
|
|
getStyle(prop?: string | ObjectAny): StyleProps { |
|
|
getStyle(prop?: string | ObjectAny): StyleProps { |
|
|
const style = this.get('style') || {}; |
|
|
const style = this.get('style') || {}; |
|
|
const result: ObjectAny = { ...style }; |
|
|
const result: ObjectAny = { ...style }; |
|
|
|
|
|
if (this.em) { |
|
|
|
|
|
const resolvedStyle = this.resolveDataVariables({ ...result }); |
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
|
return prop && isString(prop) ? resolvedStyle[prop] : resolvedStyle; |
|
|
|
|
|
} |
|
|
return prop && isString(prop) ? result[prop] : result; |
|
|
return prop && isString(prop) ? result[prop] : result; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -77,10 +95,14 @@ export default class StyleableModel<T extends ObjectHash = any> extends Model<T> |
|
|
delete newStyle[prop]; |
|
|
delete newStyle[prop]; |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
this.convertToStyleDataVariable(newStyle); |
|
|
|
|
|
|
|
|
this.set('style', newStyle, opts as any); |
|
|
this.set('style', newStyle, opts as any); |
|
|
const diff = shallowDiff(propOrig, propNew); |
|
|
const diff = shallowDiff(propOrig, newStyle); |
|
|
// Delete the property used for partial updates
|
|
|
// Delete the property used for partial updates
|
|
|
delete diff.__p; |
|
|
delete diff.__p; |
|
|
|
|
|
|
|
|
keys(diff).forEach(pr => { |
|
|
keys(diff).forEach(pr => { |
|
|
// @ts-ignore
|
|
|
// @ts-ignore
|
|
|
const { em } = this; |
|
|
const { em } = this; |
|
|
@ -92,7 +114,61 @@ export default class StyleableModel<T extends ObjectHash = any> extends Model<T> |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
return propNew; |
|
|
this.processDataVariableStyles(newStyle); |
|
|
|
|
|
|
|
|
|
|
|
return newStyle; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
convertToStyleDataVariable(style: StyleProps) { |
|
|
|
|
|
keys(style).forEach(key => { |
|
|
|
|
|
const styleValue = style[key]; |
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
|
if (typeof styleValue === 'object' && styleValue.type === 'data-variable') { |
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
|
style[key] = new StyleDataVariable(styleValue, { em: this.em }); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
processDataVariableStyles(style: StyleProps) { |
|
|
|
|
|
keys(style).forEach(key => { |
|
|
|
|
|
const styleValue = style[key]; |
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
|
if (styleValue instanceof StyleDataVariable) { |
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
|
this.listenToDataVariable(styleValue, key); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
listenToDataVariable(dataVar: StyleDataVariable, styleProp: string) { |
|
|
|
|
|
this.listenTo(dataVar, 'change:value', (model: any) => { |
|
|
|
|
|
const newValue = model.get('value'); |
|
|
|
|
|
this.updateStyleProp(styleProp, newValue); |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
updateStyleProp(prop: string, value: string) { |
|
|
|
|
|
const style = this.getStyle(); |
|
|
|
|
|
style[prop] = value; |
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
|
this.set('style', style, { noEvent: true }); |
|
|
|
|
|
this.trigger(`change:style:${prop}`); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
resolveDataVariables(style: StyleProps): StyleProps { |
|
|
|
|
|
const resolvedStyle = { ...style }; |
|
|
|
|
|
keys(resolvedStyle).forEach(key => { |
|
|
|
|
|
const styleValue = resolvedStyle[key]; |
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
|
if (styleValue instanceof StyleDataVariable) { |
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
|
const resolvedValue = this.em?.DataSources.getValue(styleValue.get('path'), styleValue.get('value')); |
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
|
resolvedStyle[key] = resolvedValue || styleValue.get('value'); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
return resolvedStyle; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
@ -147,7 +223,7 @@ export default class StyleableModel<T extends ObjectHash = any> extends Model<T> |
|
|
const value = style[prop]; |
|
|
const value = style[prop]; |
|
|
const values = isArray(value) ? (value as string[]) : [value]; |
|
|
const values = isArray(value) ? (value as string[]) : [value]; |
|
|
|
|
|
|
|
|
values.forEach((val: string) => { |
|
|
(values as string[]).forEach((val: string) => { |
|
|
const value = `${val}${important ? ' !important' : ''}`; |
|
|
const value = `${val}${important ? ' !important' : ''}`; |
|
|
value && result.push(`${prop}:${value};`); |
|
|
value && result.push(`${prop}:${value};`); |
|
|
}); |
|
|
}); |
|
|
@ -164,9 +240,4 @@ export default class StyleableModel<T extends ObjectHash = any> extends Model<T> |
|
|
// @ts-ignore
|
|
|
// @ts-ignore
|
|
|
return this.selectorsToString ? this.selectorsToString(opts) : this.getSelectors().getFullString(); |
|
|
return this.selectorsToString ? this.selectorsToString(opts) : this.getSelectors().getFullString(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// @ts-ignore
|
|
|
|
|
|
// _validate(attr, opts) {
|
|
|
|
|
|
// return true;
|
|
|
|
|
|
// }
|
|
|
|
|
|
} |
|
|
} |
|
|
|