@rws-framework/client 2.9.3 → 2.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/cfg/_default.cfg.js +2 -0
- package/cfg/build_steps/webpack/_loaders.js +14 -6
- package/package.json +20 -10
- package/rws.webpack.config.js +18 -8
- package/src/client.ts +2 -1
- package/src/components/_attrs/_default_observable_accessor.ts +9 -0
- package/src/components/_attrs/_extended_accessor.ts +41 -0
- package/src/components/_attrs/_external_handler.ts +8 -0
- package/src/components/_attrs/_external_observable_accessor.ts +9 -0
- package/src/components/_attrs/angular-attr.ts +33 -63
- package/src/components/_attrs/external-attr.ts +60 -0
- package/src/components/_attrs/external-observable.ts +44 -63
- package/src/components/_component.ts +36 -21
- package/src/components/_decorator.ts +20 -2
- package/src/components/_decorators/RWSInject.ts +2 -1
- package/src/index.ts +5 -1
- package/src/plugins/_plugin.ts +2 -1
- package/src/types/IRWSConfig.ts +3 -3
- package/src/types/IRWSPlugin.ts +19 -0
- package/webpack/loaders/rws_fast_html_loader.js +14 -0
- package/webpack/loaders/rws_fast_scss_loader.js +8 -59
- package/webpack/loaders/rws_fast_ts_loader.js +28 -17
package/README.md
CHANGED
|
@@ -379,8 +379,10 @@ const options?: RWSDecoratorOptions;
|
|
|
379
379
|
class WebChat extends RWSViewComponent {
|
|
380
380
|
@attr tagAttr: string; //HTML tag attr
|
|
381
381
|
@ngAttr fromNgAttr: string; //HTML attr from angular template
|
|
382
|
+
@externalAttr fromExAttr: string; //HTML attr with change observation
|
|
382
383
|
@sanitizedAttr htmlAttr: string; //HTML attr that's sanitized with every val change
|
|
383
384
|
@observable someVar: any; //Var for templates/value change observation
|
|
385
|
+
@externalObservable someExVar: string; //Var for templates/value change observation with external watch
|
|
384
386
|
}
|
|
385
387
|
```
|
|
386
388
|
|
package/cfg/_default.cfg.js
CHANGED
|
@@ -9,11 +9,13 @@ function getRWSLoaders(packageDir, nodeModulesPath, tsConfigPath){
|
|
|
9
9
|
|
|
10
10
|
return [
|
|
11
11
|
{
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
test: /\.html$/,
|
|
13
|
+
use: [
|
|
14
|
+
{
|
|
15
|
+
loader: htmlLoader,
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
},
|
|
17
19
|
{
|
|
18
20
|
test: /\.(ts)$/,
|
|
19
21
|
use: [
|
|
@@ -33,7 +35,13 @@ function getRWSLoaders(packageDir, nodeModulesPath, tsConfigPath){
|
|
|
33
35
|
/\.debug\.ts$/,
|
|
34
36
|
/\.d\.ts$/,
|
|
35
37
|
],
|
|
36
|
-
}
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
test: /\.scss$/i,
|
|
41
|
+
use: [
|
|
42
|
+
scssLoader,
|
|
43
|
+
],
|
|
44
|
+
},
|
|
37
45
|
]
|
|
38
46
|
}
|
|
39
47
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rws-framework/client",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "2.9.
|
|
5
|
-
"main": "src/index.ts",
|
|
4
|
+
"version": "2.9.6",
|
|
5
|
+
"main": "src/index.ts",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"docs": "typedoc --tsconfig ./tsconfig.json"
|
|
8
8
|
},
|
|
@@ -30,27 +30,36 @@
|
|
|
30
30
|
"@microsoft/fast-foundation": "^2.46.2",
|
|
31
31
|
"@rws-framework/console": "*",
|
|
32
32
|
"@types/moment": "^2.13.0",
|
|
33
|
-
"dragula": "^3.7.3",
|
|
34
33
|
"deepmerge": "^4.3.1",
|
|
34
|
+
"dragula": "^3.7.3",
|
|
35
35
|
"he": "^1.2.0",
|
|
36
36
|
"json5": "^2.2.3",
|
|
37
37
|
"lodash": "^4.17.21",
|
|
38
38
|
"moment": "^2.29.4",
|
|
39
|
+
"node-sass": "^7.0.3",
|
|
39
40
|
"partial-json-parser": "^1.0.0",
|
|
40
41
|
"reflect-metadata": "^0.1.13",
|
|
41
42
|
"resolve-url-loader": "^5.0.0",
|
|
42
43
|
"sanitize-html": "^2.12.1",
|
|
43
|
-
"sass": "
|
|
44
|
+
"sass": "1.69.7",
|
|
45
|
+
"sass-loader": "^13.3.2",
|
|
44
46
|
"scss-loading-animations": "^1.0.1",
|
|
45
47
|
"socket.io-client": "^4.7.2",
|
|
48
|
+
"source-map": "^0.7.4",
|
|
49
|
+
"source-map-support": "^0.5.21",
|
|
50
|
+
"stacktrace-gps": "^3.1.2",
|
|
51
|
+
"style-loader": "^3.3.3",
|
|
52
|
+
"terser-webpack-plugin": "^5.3.9",
|
|
46
53
|
"ts-loader": "^9.4.4",
|
|
54
|
+
"ts-transformer-keys": "^0.4.4",
|
|
47
55
|
"tsc-watch": "^6.0.4",
|
|
48
56
|
"tslib": "^2.6.2",
|
|
57
|
+
"uglify-js": "^3.17.4",
|
|
49
58
|
"upload": "^1.3.2",
|
|
50
59
|
"url-router": "^13.0.0",
|
|
51
60
|
"uuid": "^9.0.1",
|
|
52
|
-
"v4": "^0.0.1"
|
|
53
|
-
|
|
61
|
+
"v4": "^0.0.1",
|
|
62
|
+
"webpack": "^5.89.0"
|
|
54
63
|
},
|
|
55
64
|
"devDependencies": {
|
|
56
65
|
"@types/dragula": "^3.7.4",
|
|
@@ -60,7 +69,8 @@
|
|
|
60
69
|
"@types/he": "^1.2.3",
|
|
61
70
|
"@types/sanitize-html": "^2.11.0",
|
|
62
71
|
"@types/uuid": "^9.0.7",
|
|
63
|
-
"@typescript-eslint/parser": "^5.0.0",
|
|
72
|
+
"@typescript-eslint/parser": "^5.0.0",
|
|
73
|
+
"browser-sync": "^2.29.3",
|
|
64
74
|
"clean-webpack-plugin": "^4.0.0",
|
|
65
75
|
"css-loader": "^6.8.1",
|
|
66
76
|
"css-minimizer-webpack-plugin": "^5.0.1",
|
|
@@ -71,12 +81,12 @@
|
|
|
71
81
|
"mini-css-extract-plugin": "^2.7.6",
|
|
72
82
|
"minimatch": "^9.0.4",
|
|
73
83
|
"node-sass": "^9.0.0",
|
|
84
|
+
"raw-loader": "^4.0.2",
|
|
74
85
|
"sass-loader": "^13.3.2",
|
|
75
86
|
"source-map": "^0.7.4",
|
|
76
87
|
"style-loader": "^3.3.3",
|
|
77
88
|
"terser-webpack-plugin": "^5.3.9",
|
|
78
|
-
"ts-loader": "^9.4.4",
|
|
79
|
-
"raw-loader": "^4.0.2",
|
|
89
|
+
"ts-loader": "^9.4.4",
|
|
80
90
|
"ts-node": "^10.9.1",
|
|
81
91
|
"tsconfig-paths": "^4.2.0",
|
|
82
92
|
"tsconfig-paths-webpack-plugin": "^4.1.0",
|
|
@@ -86,7 +96,7 @@
|
|
|
86
96
|
"typedoc-plugin-rename-defaults": "^0.7.0",
|
|
87
97
|
"typedoc-theme-hierarchy": "^4.1.2",
|
|
88
98
|
"typescript": "^5.1.6",
|
|
89
|
-
"url-loader": "^4.1.1",
|
|
99
|
+
"url-loader": "^4.1.1",
|
|
90
100
|
"webpack": "^5.75.0",
|
|
91
101
|
"webpack-bundle-analyzer": "^4.10.1",
|
|
92
102
|
"webpack-cli": "^5.1.4",
|
package/rws.webpack.config.js
CHANGED
|
@@ -5,6 +5,8 @@ const webpack = require('webpack');
|
|
|
5
5
|
const { rwsPath, RWSConfigBuilder } = require('@rws-framework/console');
|
|
6
6
|
|
|
7
7
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
8
|
+
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
|
|
9
|
+
|
|
8
10
|
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
|
9
11
|
const TerserPlugin = require('terser-webpack-plugin');
|
|
10
12
|
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
|
@@ -24,7 +26,7 @@ const { _DEFAULT_CONFIG } = require('./cfg/_default.cfg');
|
|
|
24
26
|
const { info } = require('console');
|
|
25
27
|
|
|
26
28
|
const _MAIN_PACKAGE = rwsPath.findRootWorkspacePath(process.cwd());
|
|
27
|
-
|
|
29
|
+
console.log(process.argv);
|
|
28
30
|
const RWSWebpackWrapper = async (config) => {
|
|
29
31
|
const BuildConfigurator = new RWSConfigBuilder(rwsPath.findPackageDir(process.cwd()) + '/.rws.json', {..._DEFAULT_CONFIG, ...config});
|
|
30
32
|
|
|
@@ -52,6 +54,7 @@ const RWSWebpackWrapper = async (config) => {
|
|
|
52
54
|
|
|
53
55
|
const devTools = isDev ? (BuildConfigurator.get('devtool') || 'source-map') : false;
|
|
54
56
|
const devDebug = isDev ? (BuildConfigurator.get('devDebug') || config.devDebug || { build: false }) : null;
|
|
57
|
+
const devRouteProxy = BuildConfigurator.get('devRouteProxy') || config.devRouteProxy;
|
|
55
58
|
|
|
56
59
|
const tsConfigPath = rwsPath.relativize(BuildConfigurator.get('tsConfigPath') || config.tsConfigPath, executionDir);
|
|
57
60
|
const rwsPlugins = {};
|
|
@@ -283,7 +286,7 @@ const RWSWebpackWrapper = async (config) => {
|
|
|
283
286
|
sourceMapFilename: '[file].map',
|
|
284
287
|
},
|
|
285
288
|
resolve: {
|
|
286
|
-
extensions: ['.ts', '.js'],
|
|
289
|
+
extensions: ['.ts', '.js', '.scss', '.css'],
|
|
287
290
|
modules: modules_setup,
|
|
288
291
|
alias: {
|
|
289
292
|
...aliases
|
|
@@ -302,18 +305,25 @@ const RWSWebpackWrapper = async (config) => {
|
|
|
302
305
|
cfgExport.optimization = optimConfig;
|
|
303
306
|
}
|
|
304
307
|
|
|
305
|
-
|
|
306
|
-
cfgExport.devServer = {
|
|
307
|
-
hot: true,
|
|
308
|
-
static: publicDir
|
|
309
|
-
}
|
|
310
|
-
}
|
|
308
|
+
|
|
311
309
|
|
|
312
310
|
for (const pluginKey of Object.keys(rwsPlugins)){
|
|
313
311
|
const plugin = rwsPlugins[pluginKey];
|
|
314
312
|
cfgExport = await plugin.onBuild(cfgExport);
|
|
315
313
|
}
|
|
316
314
|
|
|
315
|
+
if(isDev){
|
|
316
|
+
const backendUrl = BuildConfigurator.get('backendUrl') || config.backendUrl;
|
|
317
|
+
const apiPort = BuildConfigurator.get('apiPort') || config.apiPort;
|
|
318
|
+
|
|
319
|
+
if(backendUrl && apiPort){
|
|
320
|
+
// cfgExport.devServer = {
|
|
321
|
+
// hot: true, // Enable hot module replacement
|
|
322
|
+
// open: true, // Automatically open the browser
|
|
323
|
+
// }
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
317
327
|
return cfgExport;
|
|
318
328
|
}
|
|
319
329
|
|
package/src/client.ts
CHANGED
|
@@ -23,6 +23,7 @@ import ComponentHelper, { ComponentHelperStatic, RWSInfoType } from './client/co
|
|
|
23
23
|
import ServicesHelper from './client/services';
|
|
24
24
|
import ConfigHelper from './client/config';
|
|
25
25
|
import { DefaultRWSPluginOptionsType, RWSPlugin } from './plugins/_plugin';
|
|
26
|
+
import { IStaticRWSPlugin } from './types/IRWSPlugin'
|
|
26
27
|
|
|
27
28
|
interface IHotModule extends NodeModule {
|
|
28
29
|
hot?: {
|
|
@@ -73,7 +74,7 @@ class RWSClient {
|
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
addPlugin<T extends DefaultRWSPluginOptionsType>(pluginEntry:
|
|
77
|
+
addPlugin<T extends DefaultRWSPluginOptionsType>(pluginEntry: IStaticRWSPlugin)
|
|
77
78
|
{
|
|
78
79
|
this.config.plugins.push(pluginEntry);
|
|
79
80
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Accessor, Observable } from "@microsoft/fast-element";
|
|
2
|
+
import { ExtendedObservableAccessor } from "./_extended_accessor";
|
|
3
|
+
|
|
4
|
+
export class DefaultObservableAccessor extends ExtendedObservableAccessor {
|
|
5
|
+
|
|
6
|
+
constructor(public name: string, protected customGet: (source: any, field: string) => any = null, protected customSet: (source: any, field: string, newVal: any) => boolean | void = null, protected watcher: any = void 0, suffix: string = 'Changed') {
|
|
7
|
+
super(name, customGet, customSet, watcher, suffix);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Observable, Accessor } from "@microsoft/fast-element";
|
|
2
|
+
|
|
3
|
+
export abstract class ExtendedObservableAccessor implements Accessor {
|
|
4
|
+
protected field: string;
|
|
5
|
+
protected callback: string;
|
|
6
|
+
|
|
7
|
+
constructor(public name: string, protected customGet: (source: any, field: string) => any = null, protected customSet: (source: any, field: string, newVal: any) => boolean | void = null, protected watcher: any = void 0, suffix: string = 'Changed') {
|
|
8
|
+
this.field = `_${name}`;
|
|
9
|
+
this.callback = `${name}${suffix}`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
getValue(source: any): any {
|
|
13
|
+
Observable.track(source, this.name);
|
|
14
|
+
|
|
15
|
+
return this.customGet ? this.customGet(source, this.field) : source[this.field];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
setValue(source: any, newValue: any): void {
|
|
19
|
+
if(this.customSet){
|
|
20
|
+
if(this.customSet(source, this.field, newValue) === false){
|
|
21
|
+
return;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const field = this.field;
|
|
26
|
+
const oldValue = source[field];
|
|
27
|
+
|
|
28
|
+
if (oldValue !== newValue) {
|
|
29
|
+
source[field] = newValue;
|
|
30
|
+
|
|
31
|
+
const callback = source[this.callback];
|
|
32
|
+
|
|
33
|
+
if (typeof callback === 'function') {
|
|
34
|
+
callback.call(source, oldValue, newValue);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
Observable.getNotifier(source).notify(this.name);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Accessor, Observable } from "@microsoft/fast-element";
|
|
2
|
+
import { ExtendedObservableAccessor } from "./_extended_accessor";
|
|
3
|
+
|
|
4
|
+
export class ExternalObservableAccessor extends ExtendedObservableAccessor {
|
|
5
|
+
|
|
6
|
+
constructor(public name: string, protected customGet: (source: any, field: string) => any = null, protected customSet: (source: any, field: string, newVal: any) => boolean | void = null, protected watcher: any = void 0) {
|
|
7
|
+
super(name, customGet, customSet, watcher, '');
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -1,64 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
{
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
Object.defineProperty(target, privatePropName, {
|
|
35
|
-
writable: true,
|
|
36
|
-
value: target[propertyKey],
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
Object.defineProperty(target, propertyKey, {
|
|
40
|
-
get() {
|
|
41
|
-
const value: string = this[privatePropName];
|
|
42
|
-
return isNgValue(value) ? null : value;
|
|
43
|
-
},
|
|
44
|
-
set(value: any) {
|
|
45
|
-
if (typeof value === 'string' && isNgValue(value)) {
|
|
46
|
-
this[privatePropName] = null; // Set to null if condition is met
|
|
47
|
-
} else {
|
|
48
|
-
this[privatePropName] = value;
|
|
49
|
-
}
|
|
50
|
-
Observable.notify(this, propertyKey);
|
|
51
|
-
},
|
|
52
|
-
});
|
|
1
|
+
import {
|
|
2
|
+
DecoratorAttributeConfiguration,
|
|
3
|
+
AttributeConfiguration,
|
|
4
|
+
Observable,
|
|
5
|
+
} from "@microsoft/fast-element";
|
|
6
|
+
import { handleExternalChange } from "./_external_handler";
|
|
7
|
+
import RWSViewComponent, { IWithCompose } from "../_component";
|
|
8
|
+
import { externalAttr } from "./external-attr";
|
|
9
|
+
|
|
10
|
+
export function ngAttr(
|
|
11
|
+
config?: DecoratorAttributeConfiguration
|
|
12
|
+
): (target: {}, property: string) => void;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Decorator: Specifies an HTML attribute.
|
|
16
|
+
* @param target - The class to define the attribute on.
|
|
17
|
+
* @param prop - The property name to be associated with the attribute.
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
export function ngAttr(target: {}, prop: string): void;
|
|
21
|
+
export function ngAttr(
|
|
22
|
+
configOrTarget?: DecoratorAttributeConfiguration | {},
|
|
23
|
+
prop?: string
|
|
24
|
+
): void | ((target: {}, property: string) => void) {
|
|
25
|
+
return externalAttr(configOrTarget, prop, {
|
|
26
|
+
converter: (val: any) => {
|
|
27
|
+
if(val && val.indexOf('{{') > -1){
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return val;
|
|
32
|
+
}
|
|
33
|
+
})
|
|
53
34
|
}
|
|
54
|
-
|
|
55
|
-
function isNgValue(input: string): boolean {
|
|
56
|
-
// Regular expression to match AngularJS template variable notation
|
|
57
|
-
const angularJsVariablePattern = /\{\{([^}]+)\}\}/;
|
|
58
|
-
|
|
59
|
-
// Test the input string for the pattern and return the result
|
|
60
|
-
return angularJsVariablePattern.test(input);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
export { ngAttr };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DecoratorAttributeConfiguration,
|
|
3
|
+
AttributeConfiguration,
|
|
4
|
+
Observable,
|
|
5
|
+
} from "@microsoft/fast-element";
|
|
6
|
+
import { handleExternalChange } from "./_external_handler";
|
|
7
|
+
import RWSViewComponent, { IWithCompose } from "../_component";
|
|
8
|
+
|
|
9
|
+
type ExAttrOpts = { converter?: (val: any) => string }
|
|
10
|
+
const _default_opts = {
|
|
11
|
+
converter: (val: any) => {
|
|
12
|
+
return val;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function externalAttr(
|
|
17
|
+
config?: DecoratorAttributeConfiguration,
|
|
18
|
+
): (target: {}, property: string) => void;
|
|
19
|
+
|
|
20
|
+
export function externalAttr(target: {}, property: string, opts?: ExAttrOpts): void;
|
|
21
|
+
export function externalAttr(
|
|
22
|
+
configOrTarget?: DecoratorAttributeConfiguration | {},
|
|
23
|
+
property?: string,
|
|
24
|
+
opts: ExAttrOpts = _default_opts
|
|
25
|
+
): void | ((target: {}, property: string) => void) {
|
|
26
|
+
let config: AttributeConfiguration;
|
|
27
|
+
|
|
28
|
+
function decorator($target: {}, $prop: string): void {
|
|
29
|
+
if (arguments.length > 1) {
|
|
30
|
+
// Non invocation:
|
|
31
|
+
// - @attr
|
|
32
|
+
// Invocation with or w/o opts:
|
|
33
|
+
// - @attr()
|
|
34
|
+
// - @attr({...opts})
|
|
35
|
+
config.property = $prop;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
config.mode = 'fromView';
|
|
39
|
+
config.converter = { fromView: opts.converter, toView: null };
|
|
40
|
+
|
|
41
|
+
const attrs = AttributeConfiguration.locate($target.constructor);
|
|
42
|
+
RWSViewComponent.setExternalAttr(($target.constructor as IWithCompose<any>).name, $prop);
|
|
43
|
+
|
|
44
|
+
attrs.push(config);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (arguments.length > 1) {
|
|
48
|
+
// Non invocation:
|
|
49
|
+
// - @attr
|
|
50
|
+
config = {} as any;
|
|
51
|
+
decorator(configOrTarget!, property!);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Invocation with or w/o opts:
|
|
56
|
+
// - @attr()
|
|
57
|
+
// - @attr({...opts})
|
|
58
|
+
config = configOrTarget === void 0 ? ({} as any) : configOrTarget;
|
|
59
|
+
return decorator;
|
|
60
|
+
}
|
|
@@ -1,72 +1,53 @@
|
|
|
1
|
-
import { Observable } from '@microsoft/fast-element';
|
|
2
|
-
import RWSViewComponent from '../_component';
|
|
3
|
-
import DOMService from '../../services/DOMService';
|
|
4
|
-
import RWSContainer from '../_container';
|
|
5
|
-
import { IOptions } from 'sanitize-html';
|
|
6
|
-
|
|
7
|
-
import * as he from 'he';
|
|
8
|
-
|
|
9
|
-
type SanitizeOptions = IOptions & { fullEncode?: boolean };
|
|
1
|
+
import { Observable, Accessor, observable as parentObservable} from '@microsoft/fast-element';
|
|
10
2
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
function enc(html: string): string
|
|
17
|
-
{
|
|
18
|
-
return he.encode(html, heOpt);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const transformAnyTag = (tagName: string, attribs: { [key: string]: string }) => {
|
|
23
|
-
// Example: Wrap the original tag with `span` and indicate the original tag name in a data attribute
|
|
24
|
-
return {
|
|
25
|
-
tagName: 'span', // Change this to any tag you want to transform to
|
|
26
|
-
attribs: {
|
|
27
|
-
...attribs,
|
|
28
|
-
'data-original-tag': tagName
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
};
|
|
3
|
+
import RWSViewComponent from '../_component';
|
|
4
|
+
import { DefaultObservableAccessor } from './_default_observable_accessor';
|
|
5
|
+
import { ExternalObservableAccessor } from './_external_observable_accessor';
|
|
32
6
|
|
|
33
|
-
function applyDecorator(target: RWSViewComponent, prop: string, config: SanitizeOptions = null): void
|
|
34
|
-
{
|
|
35
|
-
modifyPropertyDescriptor(target, prop, config as IOptions);
|
|
36
|
-
}
|
|
37
7
|
|
|
38
|
-
|
|
39
|
-
const privatePropName = `_${String(propertyKey)}`;
|
|
40
|
-
Object.defineProperty(target, privatePropName, {
|
|
41
|
-
writable: true,
|
|
42
|
-
value: target[propertyKey],
|
|
43
|
-
});
|
|
8
|
+
type ExternalObservableOptions = {} | unknown;
|
|
44
9
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return this[privatePropName];
|
|
48
|
-
},
|
|
49
|
-
set(value: any) {
|
|
50
|
-
console.log('[DEBUG] external changed', propertyKey);
|
|
51
|
-
this[privatePropName] = value;
|
|
52
|
-
Observable.notify(this, propertyKey);
|
|
53
|
-
},
|
|
54
|
-
});
|
|
10
|
+
function isString(test: unknown){
|
|
11
|
+
return typeof test === 'string';
|
|
55
12
|
}
|
|
56
13
|
|
|
57
|
-
function
|
|
58
|
-
{
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
14
|
+
function externalObservable(targetComponent: RWSViewComponent | unknown, nameOrAccessor: string | Accessor, opts: ExternalObservableOptions = null): void | any
|
|
15
|
+
{
|
|
16
|
+
|
|
17
|
+
const target = targetComponent as any;
|
|
18
|
+
const propName = typeof nameOrAccessor === 'string' ? nameOrAccessor : nameOrAccessor.name;
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
if (isString(nameOrAccessor)) {
|
|
22
|
+
nameOrAccessor = new DefaultObservableAccessor(propName);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const defaultAccessor: Accessor = nameOrAccessor as Accessor;
|
|
26
|
+
const extendedAccessor = new ExternalObservableAccessor(propName);
|
|
27
|
+
|
|
28
|
+
const accessors: Accessor[] = [
|
|
29
|
+
defaultAccessor,
|
|
30
|
+
extendedAccessor
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
for (const accessor of accessors){
|
|
34
|
+
Observable.getAccessors(target).push(accessor);
|
|
35
|
+
|
|
36
|
+
Reflect.defineProperty(target, accessor.name, {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get(this: any) {
|
|
39
|
+
return accessor.getValue(this);
|
|
40
|
+
},
|
|
41
|
+
set(this: any, newValue: any) {
|
|
42
|
+
const oldVal = accessor.getValue(this);
|
|
43
|
+
accessor.setValue(this, newValue);
|
|
44
|
+
if(!!this['externalChanged']){
|
|
45
|
+
this['externalChanged'].call(accessor.name, oldVal, newValue);
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
69
50
|
}
|
|
70
51
|
|
|
71
52
|
|
|
72
|
-
export {
|
|
53
|
+
export { externalObservable };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ViewTemplate, ElementStyles, observable, html, Constructable, PartialFASTElementDefinition, attr } from '@microsoft/fast-element';
|
|
1
|
+
import { ViewTemplate, ElementStyles, observable, html, Constructable, PartialFASTElementDefinition, attr, Observable } from '@microsoft/fast-element';
|
|
2
2
|
import { FoundationElement, FoundationElementDefinition, FoundationElementRegistry, OverrideFoundationElementDefinition } from '../../foundation/rws-foundation';
|
|
3
3
|
import ConfigService, { ConfigServiceInstance } from '../services/ConfigService';
|
|
4
4
|
import UtilsService, { UtilsServiceInstance } from '../services/UtilsService';
|
|
@@ -9,6 +9,7 @@ import { IRWSViewComponent, IAssetShowOptions } from '../types/IRWSViewComponent
|
|
|
9
9
|
import RWSWindow, { RWSWindowComponentInterface, loadRWSRichWindow } from '../types/RWSWindow';
|
|
10
10
|
import { applyConstructor, RWSInject } from './_decorator';
|
|
11
11
|
import TheRWSService from '../services/_service';
|
|
12
|
+
import { handleExternalChange } from './_attrs/_external_handler';
|
|
12
13
|
|
|
13
14
|
interface IFastDefinition {
|
|
14
15
|
name: string;
|
|
@@ -32,10 +33,13 @@ export interface IWithCompose<T extends RWSViewComponent> {
|
|
|
32
33
|
_verbose: boolean;
|
|
33
34
|
_toInject: {[key: string]: TheRWSService};
|
|
34
35
|
_depKeys: {[key: string]: string[]};
|
|
36
|
+
_externalAttrs: { [key:string]: string[] };
|
|
37
|
+
setExternalAttr: (componentName: string, key: string) => void
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
abstract class RWSViewComponent extends FoundationElement implements IRWSViewComponent {
|
|
38
41
|
__isLoading: boolean = true;
|
|
42
|
+
__exAttrLoaded: string[] = [];
|
|
39
43
|
private static instances: RWSViewComponent[] = [];
|
|
40
44
|
static fileList: string[] = [];
|
|
41
45
|
|
|
@@ -45,6 +49,7 @@ abstract class RWSViewComponent extends FoundationElement implements IRWSViewCom
|
|
|
45
49
|
static _defined: { [key: string]: boolean } = {};
|
|
46
50
|
static _toInject: {[key: string]: TheRWSService} = {};
|
|
47
51
|
static _depKeys: {[key: string]: string[]} = {_all: []};
|
|
52
|
+
static _externalAttrs: { [key: string]: string[] } = {};
|
|
48
53
|
static _verbose: boolean = false;
|
|
49
54
|
|
|
50
55
|
@RWSInject(ConfigService, true) protected config: ConfigServiceInstance;
|
|
@@ -60,34 +65,18 @@ abstract class RWSViewComponent extends FoundationElement implements IRWSViewCom
|
|
|
60
65
|
|
|
61
66
|
constructor() {
|
|
62
67
|
super();
|
|
63
|
-
applyConstructor(this);
|
|
64
|
-
|
|
68
|
+
applyConstructor(this);
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
connectedCallback() {
|
|
68
72
|
super.connectedCallback();
|
|
69
|
-
applyConstructor(this);
|
|
70
|
-
|
|
71
|
-
// console.trace(this.config);
|
|
72
|
-
// console.log(this.routingService);
|
|
73
|
+
applyConstructor(this);
|
|
74
|
+
|
|
73
75
|
if (!(this.constructor as IWithCompose<this>).definition && (this.constructor as IWithCompose<this>).autoLoadFastElement) {
|
|
74
76
|
throw new Error('RWS component is not named. Add `static definition = {name, template};`');
|
|
75
77
|
}
|
|
76
78
|
|
|
77
|
-
|
|
78
|
-
(this.constructor as IWithCompose<this>).fileList.forEach((file: string) => {
|
|
79
|
-
if (this.fileAssets[file]) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
this.apiService.pureGet(this.config.get('pubUrlFilePrefix') + file).then((response: string) => {
|
|
83
|
-
this.fileAssets = { ...this.fileAssets, [file]: html`${response}` };
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
} catch (e: Error | any) {
|
|
88
|
-
console.error('Error loading file content:', e.message);
|
|
89
|
-
console.error(e.stack);
|
|
90
|
-
}
|
|
79
|
+
this.applyFileList();
|
|
91
80
|
|
|
92
81
|
RWSViewComponent.instances.push(this);
|
|
93
82
|
}
|
|
@@ -214,6 +203,32 @@ abstract class RWSViewComponent extends FoundationElement implements IRWSViewCom
|
|
|
214
203
|
this.$emit(eventName, event);
|
|
215
204
|
}
|
|
216
205
|
|
|
206
|
+
private applyFileList(): void
|
|
207
|
+
{
|
|
208
|
+
try {
|
|
209
|
+
(this.constructor as IWithCompose<this>).fileList.forEach((file: string) => {
|
|
210
|
+
if (this.fileAssets[file]) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
this.apiService.pureGet(this.config.get('pubUrlFilePrefix') + file).then((response: string) => {
|
|
214
|
+
this.fileAssets = { ...this.fileAssets, [file]: html`${response}` };
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
} catch (e: Error | any) {
|
|
219
|
+
console.error('Error loading file content:', e.message);
|
|
220
|
+
console.error(e.stack);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
static setExternalAttr(componentName: string, key: string)
|
|
225
|
+
{
|
|
226
|
+
if(!Object.keys(RWSViewComponent._externalAttrs).includes(componentName)){
|
|
227
|
+
RWSViewComponent._externalAttrs[componentName] = [];
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
RWSViewComponent._externalAttrs[componentName].push(key);
|
|
231
|
+
}
|
|
217
232
|
|
|
218
233
|
static hotReplacedCallback() {
|
|
219
234
|
this.getInstances().forEach(instance => instance.forceReload());
|
|
@@ -5,7 +5,8 @@ import { loadRWSRichWindow } from '../types/RWSWindow';
|
|
|
5
5
|
import RWSViewComponent, { IWithCompose } from './_component';
|
|
6
6
|
import { InterfaceSymbol } from './_container';
|
|
7
7
|
import { RWSInject } from './_decorators/RWSInject';
|
|
8
|
-
import { ElementStyles, ViewTemplate } from '@microsoft/fast-element';
|
|
8
|
+
import { ElementStyles, Observable, ViewTemplate } from '@microsoft/fast-element';
|
|
9
|
+
import { handleExternalChange } from './_attrs/_external_handler';
|
|
9
10
|
|
|
10
11
|
interface RWSDecoratorOptions {
|
|
11
12
|
template?: string,
|
|
@@ -77,10 +78,12 @@ const applyConstructor = (component: RWSViewComponent, x: boolean = false): void
|
|
|
77
78
|
|
|
78
79
|
type KeyType = {[key: string]: TheRWSService | string };
|
|
79
80
|
|
|
81
|
+
const _target = (component as any);
|
|
82
|
+
|
|
80
83
|
function inject(services: KeyType){
|
|
81
84
|
for (const prop in services) {
|
|
82
85
|
const service = (typeof services[prop] === 'string' ? existingInjectedDependencies[prop] : services[prop]) as TheRWSService;
|
|
83
|
-
|
|
86
|
+
_target[prop] = service;
|
|
84
87
|
}
|
|
85
88
|
}
|
|
86
89
|
|
|
@@ -100,6 +103,21 @@ const applyConstructor = (component: RWSViewComponent, x: boolean = false): void
|
|
|
100
103
|
inject({
|
|
101
104
|
config: RWSContainer().get(ConfigService)
|
|
102
105
|
})
|
|
106
|
+
|
|
107
|
+
if(Object.keys(RWSViewComponent._externalAttrs).includes((_target.constructor as IWithCompose<any>).name)){
|
|
108
|
+
for(const exAttrKey in RWSViewComponent._externalAttrs[(_target.constructor as IWithCompose<any>).name]){
|
|
109
|
+
const exAttr = RWSViewComponent._externalAttrs[(_target.constructor as IWithCompose<any>).name][exAttrKey];
|
|
110
|
+
const notifier = Observable.getNotifier(_target);
|
|
111
|
+
notifier.subscribe({
|
|
112
|
+
handleChange(source, key) {
|
|
113
|
+
if (key === exAttr && !_target.__exAttrLoaded.includes(exAttr)) {
|
|
114
|
+
handleExternalChange(source, key);
|
|
115
|
+
_target.__exAttrLoaded.push(key);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}, exAttr);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
103
121
|
};
|
|
104
122
|
|
|
105
123
|
export { RWSView, RWSDecoratorOptions, RWSIgnore, RWSInject, applyConstructor };
|
|
@@ -2,6 +2,7 @@ import { Key } from '../_container';
|
|
|
2
2
|
import RWSViewComponent, { IWithCompose } from '../_component';
|
|
3
3
|
import { loadDep, getFunctionParamNames } from './_di';
|
|
4
4
|
import TheRWSService from '../../services/_service';
|
|
5
|
+
import { handleExternalChange } from '../_attrs/_external_handler';
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
type InjectDecoratorReturnType = (target: any, key?: string | number | undefined, parameterIndex?: number) => void;
|
|
@@ -40,7 +41,7 @@ function RWSInject<T extends RWSViewComponent>(dependencyClass: Key, defaultServ
|
|
|
40
41
|
const depKey = paramNames[parameterIndex];
|
|
41
42
|
|
|
42
43
|
addToComponentInjection(targetConstructor.name, targetConstructor, depKey, dependencyClass, defaultService);
|
|
43
|
-
}
|
|
44
|
+
}
|
|
44
45
|
};
|
|
45
46
|
}
|
|
46
47
|
|
package/src/index.ts
CHANGED
|
@@ -11,8 +11,10 @@ import UtilsService, {UtilsServiceInstance} from './services/UtilsService';
|
|
|
11
11
|
import ServiceWorkerService, { ServiceWorkerServiceInstance } from './services/ServiceWorkerService';
|
|
12
12
|
import { sanitizedAttr } from './components/_attrs/sanitize-html';
|
|
13
13
|
import { ngAttr } from './components/_attrs/angular-attr';
|
|
14
|
-
import {
|
|
14
|
+
import { externalObservable } from './components/_attrs/external-observable';
|
|
15
|
+
import { externalAttr } from './components/_attrs/external-attr';
|
|
15
16
|
import { RWSPlugin, DefaultRWSPluginOptionsType } from './plugins/_plugin';
|
|
17
|
+
import { IRWSPlugin, IStaticRWSPlugin } from './types/IRWSPlugin';
|
|
16
18
|
import RWSClient, { RWSClientInstance } from './client';
|
|
17
19
|
import { RWSPluginEntry } from './types/IRWSConfig';
|
|
18
20
|
import IRWSUser from './types/IRWSUser';
|
|
@@ -32,6 +34,7 @@ export {
|
|
|
32
34
|
|
|
33
35
|
RWSPlugin,
|
|
34
36
|
RWSPluginEntry,
|
|
37
|
+
IRWSPlugin, IStaticRWSPlugin,
|
|
35
38
|
DefaultRWSPluginOptionsType,
|
|
36
39
|
|
|
37
40
|
NotifyUiType,
|
|
@@ -69,6 +72,7 @@ export {
|
|
|
69
72
|
RWSIgnore,
|
|
70
73
|
RWSInject,
|
|
71
74
|
observable,
|
|
75
|
+
externalObservable,
|
|
72
76
|
externalAttr,
|
|
73
77
|
attr,
|
|
74
78
|
ngAttr,
|
package/src/plugins/_plugin.ts
CHANGED
|
@@ -3,11 +3,12 @@ import { Container } from "../components/_container";
|
|
|
3
3
|
import RWSWindow, {loadRWSRichWindow } from '../types/RWSWindow';
|
|
4
4
|
import IRWSUser from "../types/IRWSUser";
|
|
5
5
|
import { RWSInfoType } from "../client/components";
|
|
6
|
+
import { IRWSPlugin } from "../types/IRWSPlugin";
|
|
6
7
|
|
|
7
8
|
type DefaultRWSPluginOptionsType = { enabled: boolean };
|
|
8
9
|
type PluginInfoType = { name: string }
|
|
9
10
|
type PluginConstructor<T extends DefaultRWSPluginOptionsType> = new (options: T) => RWSPlugin<T>;
|
|
10
|
-
abstract class RWSPlugin<PluginOptions extends DefaultRWSPluginOptionsType> {
|
|
11
|
+
abstract class RWSPlugin<PluginOptions extends DefaultRWSPluginOptionsType> implements IRWSPlugin{
|
|
11
12
|
protected isLoaded: boolean = false;
|
|
12
13
|
protected options: PluginOptions;
|
|
13
14
|
protected container: Container;
|
package/src/types/IRWSConfig.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import RWSViewComponent from '../components/_component';
|
|
2
2
|
import { RWSPlugin, DefaultRWSPluginOptionsType } from '../plugins/_plugin';
|
|
3
|
+
import { IStaticRWSPlugin } from '../types/IRWSPlugin';
|
|
3
4
|
|
|
4
5
|
export type IFrontRoutes = Record<string, unknown>;
|
|
5
|
-
export type
|
|
6
|
-
export type RWSPluginEntry<T extends DefaultRWSPluginOptionsType> = PluginConstructor<T> | [PluginConstructor<T>, T];
|
|
6
|
+
export type RWSPluginEntry<T extends DefaultRWSPluginOptionsType = DefaultRWSPluginOptionsType> = new (...args: any[]) => RWSPlugin<T>;
|
|
7
7
|
|
|
8
8
|
export default interface IRWSConfig {
|
|
9
9
|
dev?: boolean
|
|
@@ -23,7 +23,7 @@ export default interface IRWSConfig {
|
|
|
23
23
|
parted?: boolean
|
|
24
24
|
partedFileDir?: string
|
|
25
25
|
partedPrefix?: string
|
|
26
|
-
plugins?:
|
|
26
|
+
plugins?: IStaticRWSPlugin[]
|
|
27
27
|
routing_enabled?: boolean
|
|
28
28
|
_noLoad?: boolean
|
|
29
29
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DefaultRWSPluginOptionsType } from "../plugins/_plugin";
|
|
2
|
+
import IRWSUser from "./IRWSUser";
|
|
3
|
+
import { Container } from "../components/_container";
|
|
4
|
+
import RWSWindow from "../types/RWSWindow";
|
|
5
|
+
import { RWSInfoType } from "../client/components";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export interface IRWSPlugin {
|
|
9
|
+
onClientStart(): Promise<void>
|
|
10
|
+
onPartedComponentsLoad(componentParts: RWSInfoType): Promise<void>
|
|
11
|
+
onComponentsDeclare(): Promise<void>
|
|
12
|
+
onSetUser(user: IRWSUser): Promise<void>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface IStaticRWSPlugin<PluginOptions extends DefaultRWSPluginOptionsType = DefaultRWSPluginOptionsType> {
|
|
16
|
+
new (...args: any[]): IRWSPlugin;
|
|
17
|
+
container: Container;
|
|
18
|
+
window: RWSWindow;
|
|
19
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
module.exports = function(content){
|
|
5
|
+
const filePath = this.resourcePath;
|
|
6
|
+
const componentDir = path.dirname(filePath);
|
|
7
|
+
const componentPath = path.resolve(componentDir, 'component.ts');
|
|
8
|
+
|
|
9
|
+
if(fs.existsSync(componentPath)){
|
|
10
|
+
fs.writeFileSync(componentPath, fs.readFileSync(componentPath, 'utf-8'))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return '';
|
|
14
|
+
}
|
|
@@ -1,65 +1,14 @@
|
|
|
1
|
-
const RWSCssPlugin = require("../rws_scss_plugin");
|
|
2
1
|
const path = require('path');
|
|
3
|
-
const
|
|
4
|
-
// const { css } = require('@microsoft/fast-element')
|
|
2
|
+
const fs = require('fs');
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
// return function(){ return css`${code}`; }.bind(context)();
|
|
8
|
-
// }
|
|
9
|
-
|
|
10
|
-
module.exports = function(content) {
|
|
11
|
-
const plugin = new RWSCssPlugin();
|
|
4
|
+
module.exports = function(content) {
|
|
12
5
|
const filePath = this.resourcePath;
|
|
6
|
+
const componentDir = path.resolve(path.dirname(filePath), '..');
|
|
7
|
+
const componentPath = path.resolve(componentDir, 'component.ts');
|
|
13
8
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const isDev = this._compiler.options.mode === 'development';
|
|
17
|
-
|
|
18
|
-
const saveFile = content.indexOf('@save') > -1;
|
|
19
|
-
let fromTs = false;
|
|
20
|
-
|
|
21
|
-
if (plugin.checkForImporterType(this._module, 'ts')) {
|
|
22
|
-
fromTs = true;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
try {
|
|
26
|
-
const codeData = plugin.compileScssCode(content, path.dirname(filePath), null, filePath, !isDev);
|
|
27
|
-
|
|
28
|
-
const code = codeData.code;
|
|
29
|
-
const deps = codeData.dependencies;
|
|
30
|
-
|
|
31
|
-
for (const dependency of deps){
|
|
32
|
-
this.addDependency(dependency);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (fromTs && saveFile && code) {
|
|
36
|
-
plugin.writeCssFile(filePath, code);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// if(!fromTs){
|
|
40
|
-
// return (context) => makeFastResource(context, code);
|
|
41
|
-
// }
|
|
42
|
-
|
|
43
|
-
// Properly setup the context for css-loader
|
|
44
|
-
|
|
45
|
-
const callback = this.async();
|
|
46
|
-
const loaderContext = {
|
|
47
|
-
...this,
|
|
48
|
-
query: { sourceMap: isDev },
|
|
49
|
-
async: () => (err, output) => {
|
|
50
|
-
if (err) {
|
|
51
|
-
callback(err);
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
callback(null, output);
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
// Execute css-loader with the generated CSS code
|
|
59
|
-
cssLoader.call(loaderContext, code);
|
|
60
|
-
|
|
61
|
-
} catch (e) {
|
|
62
|
-
console.error(e);
|
|
63
|
-
callback(e);
|
|
9
|
+
if(fs.existsSync(componentPath)){
|
|
10
|
+
fs.writeFileSync(componentPath, fs.readFileSync(componentPath, 'utf-8'))
|
|
64
11
|
}
|
|
12
|
+
|
|
13
|
+
return '';
|
|
65
14
|
};
|
|
@@ -5,6 +5,8 @@ const ts = require('typescript');
|
|
|
5
5
|
const tools = require('../../_tools');
|
|
6
6
|
const chalk = require('chalk');
|
|
7
7
|
const {html_error_proof} = require('./ts/html_error');
|
|
8
|
+
const RWSCssPlugin = require("../rws_scss_plugin");
|
|
9
|
+
const plugin = new RWSCssPlugin();
|
|
8
10
|
|
|
9
11
|
const _defaultRWSLoaderOptions = {
|
|
10
12
|
templatePath: 'template.html',
|
|
@@ -12,9 +14,8 @@ const _defaultRWSLoaderOptions = {
|
|
|
12
14
|
fastOptions: { shadowOptions: { mode: 'open' } }
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
module.exports = async function(content) {
|
|
17
|
+
module.exports = async function(content) {
|
|
18
|
+
let htmlFastImports = null;
|
|
18
19
|
let processedContent = content;
|
|
19
20
|
const filePath = this.resourcePath;
|
|
20
21
|
const isDev = this._compiler.options.mode === 'development';
|
|
@@ -70,29 +71,39 @@ module.exports = async function(content) {
|
|
|
70
71
|
const tagName = decoratorData.tagName;
|
|
71
72
|
|
|
72
73
|
try {
|
|
73
|
-
if(tagName){
|
|
74
|
+
if(tagName){
|
|
75
|
+
const templateName = 'template';
|
|
76
|
+
const templatePath = path.dirname(filePath) + `/${templateName}.html`;
|
|
77
|
+
|
|
78
|
+
const templateExists = fs.existsSync(templatePath);
|
|
79
|
+
|
|
80
|
+
let template = 'const rwsTemplate: null = null;';
|
|
74
81
|
let styles = 'const styles: null = null;'
|
|
75
82
|
|
|
76
83
|
if(fs.existsSync(path.dirname(filePath) + '/styles')){
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
84
|
+
const scsscontent = fs.readFileSync(path.dirname(filePath) + '/' + stylesPath, 'utf-8');
|
|
85
|
+
const codeData = plugin.compileScssCode(scsscontent, path.dirname(filePath) + '/styles', null, filePath, !isDev);
|
|
86
|
+
const cssCode = codeData.code;
|
|
87
|
+
|
|
88
|
+
styles = `import './${stylesPath}';\n`;
|
|
89
|
+
if(!templateExists){
|
|
90
|
+
styles += `import { css } from '@microsoft/fast-element';\n`;
|
|
91
|
+
}
|
|
92
|
+
styles += `const styles = ${templateExists? 'T.': ''}css\`${cssCode}\`;\n`;
|
|
93
|
+
|
|
94
|
+
this.addDependency(path.dirname(filePath) + '/' + stylesPath);
|
|
95
|
+
}
|
|
80
96
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
let template = 'const rwsTemplate: null = null;';
|
|
85
|
-
|
|
86
|
-
if(templateExists){
|
|
87
|
-
const templateContent = fs.readFileSync(templatePath);
|
|
88
|
-
htmlFastImports = `import * as T from '@microsoft/fast-element';\nimport RWSTemplateHTML from './${templateName}.html';`;
|
|
89
|
-
this.addDependency(templatePath);
|
|
97
|
+
if(templateExists){
|
|
98
|
+
const templateContent = fs.readFileSync(templatePath, 'utf-8').replace(/<!--[\s\S]*?-->/g, '');
|
|
99
|
+
htmlFastImports = `import * as T from '@microsoft/fast-element';\nimport './${templateName}.html';\n`;
|
|
90
100
|
template = `
|
|
91
101
|
//@ts-ignore
|
|
92
102
|
let rwsTemplate: any = T.html\`${templateContent}\`;
|
|
93
103
|
`;
|
|
104
|
+
this.addDependency(templatePath);
|
|
94
105
|
}
|
|
95
|
-
|
|
106
|
+
|
|
96
107
|
const viewReg = /@RWSView\(['"]([a-zA-Z0-9_-]+)['"],?.*\)\sclass\s([a-zA-Z0-9_-]+) extends RWSViewComponent/gs
|
|
97
108
|
|
|
98
109
|
let m;
|