-
-
Notifications
You must be signed in to change notification settings - Fork 56
/
style-strategy.js
158 lines (158 loc) · 5.73 KB
/
style-strategy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { protocol, Origin } from 'aurelia-metadata';
import { PLATFORM } from 'aurelia-pal';
import { StyleLocator } from './style-locator';
import { relativeToFile } from 'aurelia-path';
import { StyleCompiler } from './style-compiler';
import { Loader } from 'aurelia-loader';
import { AureliaUX } from '../aurelia-ux';
/**
* Decorator: Indicates that the decorated class/object is a style strategy.
*/
export const styleStrategy = protocol.create('aurelia:style-strategy', {
validate(target) {
if (!(typeof target.loadStyleFactory === 'function')) {
return 'Style strategies must implement: loadStyleFactory(): Promise<StyleFactory>';
}
return true;
},
compose(target) {
if (!(typeof target.makeRelativeTo === 'function')) {
target.makeRelativeTo = PLATFORM.noop;
}
}
});
const cssUrlMatcher = /url\((?!['"]data)([^)]+)\)/gi;
function fixupCSSUrls(address, css) {
if (typeof css !== 'string') {
throw new Error(`Failed loading required CSS file: ${address}`);
}
return css.replace(cssUrlMatcher, (_, p1) => {
const quote = p1.charAt(0);
if (quote === '\'' || quote === '"') {
p1 = p1.substr(1, p1.length - 2);
}
return 'url(\'' + relativeToFile(p1, address) + '\')';
});
}
/**
* A style strategy that loads a style relative to its associated view-model.
*/
let RelativeStyleStrategy = class RelativeStyleStrategy {
/**
* Creates an instance of RelativeStyleStrategy.
* @param path The relative path to the styles.
*/
constructor(pathOrDesignMap) {
this.pathOrDesignMap = pathOrDesignMap;
this.absolutePath = null;
}
/**
* Loads a style factory.
*/
loadStyleFactory(container, styleObjectType) {
if (this.absolutePath === null && this.moduleId) {
const path = resolveForDesign(this.pathOrDesignMap, container);
if (!path) {
this.absolutePath = container.get(StyleLocator)
.convertOriginToStyleUrl(new Origin(this.moduleId, 'default'));
}
else {
this.absolutePath = relativeToFile(path, this.moduleId);
}
}
const styleUrl = this.absolutePath || resolveForDesign(this.pathOrDesignMap, container);
return container.get(Loader)
.loadText(styleUrl)
.catch(() => null)
.then((text) => {
text = fixupCSSUrls(styleUrl, text);
this.css = text;
const compiler = container.get(StyleCompiler);
return compiler.compile(styleObjectType, this.css);
});
}
/**
* Makes the view loaded by this strategy relative to the provided file path.
* @param file The path to load the view relative to.
*/
makeRelativeTo(file) {
if (this.absolutePath === null) {
this.absolutePath = relativeToFile(this.path, file);
}
}
};
RelativeStyleStrategy = __decorate([
styleStrategy()
], RelativeStyleStrategy);
export { RelativeStyleStrategy };
/**
* A styles strategy based on naming conventions.
*/
let ConventionalStyleStrategy = class ConventionalStyleStrategy {
/**
* Creates an instance of ConventionalStyleStrategy.
* @param viewLocator The view locator service for conventionally locating the view.
* @param origin The origin of the view model to conventionally load the view for.
*/
constructor(styleLocator, origin) {
this.moduleId = origin.moduleId;
this.styleUrl = styleLocator.convertOriginToStyleUrl(origin);
}
/**
* Loads a style factory.
*/
loadStyleFactory(container, styleObjectType) {
return container.get(Loader)
.loadText(this.styleUrl)
.catch(() => null)
.then((text) => {
text = fixupCSSUrls(this.styleUrl, text);
this.css = text;
const compiler = container.get(StyleCompiler);
return compiler.compile(styleObjectType, this.css);
});
}
};
ConventionalStyleStrategy = __decorate([
styleStrategy()
], ConventionalStyleStrategy);
export { ConventionalStyleStrategy };
/**
* A styles strategy that allows the component author to inline css.
*/
let InlineStyleStrategy = class InlineStyleStrategy {
/**
* Creates an instance of InlineStyleStrategy.
*/
constructor(cssOrDesignMap) {
this.cssOrDesignMap = cssOrDesignMap;
}
/**
* Loads a style factory.
*/
loadStyleFactory(container, styleObjectType) {
const css = resolveForDesign(this.cssOrDesignMap, container);
this.transformedCSS = fixupCSSUrls(this.moduleId, css);
const compiler = container.get(StyleCompiler);
return Promise.resolve(compiler.compile(styleObjectType, this.transformedCSS));
}
};
InlineStyleStrategy = __decorate([
styleStrategy()
], InlineStyleStrategy);
export { InlineStyleStrategy };
function resolveForDesign(valueOrDesignMap, container) {
if (typeof valueOrDesignMap === 'string') {
return valueOrDesignMap;
}
else {
const designType = container.get(AureliaUX).design.type;
return valueOrDesignMap[designType];
}
}