@shijiu/jsview 1.9.888 → 1.9.912
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/dom/bin/jsview-dom-browser.min.js +1 -0
- package/dom/bin/jsview-dom-native.min.js +1 -0
- package/dom/bin/jsview-engine-js-browser.min.js +1 -1
- package/dom/bin/jsview-forge-define.min.js +1 -1
- package/dom/index.mjs +11 -8
- package/loader/jsview-loader.js +5 -4
- package/package.json +1 -2
- package/patches/node_modules/@vue/compiler-sfc/dist/compiler-sfc.cjs.js +17 -2
- package/patches/node_modules/@vue/compiler-sfc/dist/jsview-css-to-js.js +202 -164
- package/patches/node_modules/@vue/compiler-sfc/dist/jsview-style-format.js +81 -326
- package/patches/node_modules/@vue/compiler-sfc/dist/jsview-style-types.js +67 -78
- package/patches/node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js +2 -2
- package/tools/jsview-batch-upgrade.mjs +335 -0
- package/tools/{jsview-common.js → jsview-common.mjs} +47 -14
- package/tools/{jsview-post-build.js → jsview-post-build.mjs} +8 -7
- package/tools/{jsview-post-install.js → jsview-post-install.mjs} +5 -5
- package/tools/{jsview-run-android.js → jsview-run-android.mjs} +4 -5
- package/dom/bin/jsview-browser-debug-dom.min.js +0 -1
- package/dom/bin/jsview-dom.min.js +0 -1
- package/loader/jsview-browser-forgeapp.js +0 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
/* eslint-disable */ void 0===window.Forge
|
|
1
|
+
/* eslint-disable */ void 0===window.Forge?(window.Forge={},console.log("Define forge browser")):console.log("Define using JsView forge engine-js");var e=window.Forge;class t{constructor(e,t){if(!e)return;if(!0===e.startsWith("url")){let t=e.indexOf("(")+1,i=e.lastIndexOf(")");if("undefined"===(e=e.substring(t,i).trim())||"null"===e||0===e.length)return}if(!0===e.startsWith("data:"))return void(this.href=e);let i=e.indexOf("://");if(!(i<0||i>10)||e.startsWith("./")||e.startsWith("/")||(e="./"+e),!0===e.startsWith("/"))e=document.location.origin+e;else if(!0===e.startsWith("./")&&void 0!==window.JsView&&void 0!==window.JsView.Dom.JsSubPath){if(void 0===window.JsView.Dom.MainPath||"undefined"===window.JsView.Dom.MainPathRef||window.JsView.Dom.MainPathRef!==document.location.href){window.JsView.Dom.JsSubPath.startsWith("/")||(window.JsView.Dom.JsSubPath="/"+window.JsView.Dom.JsSubPath),window.JsView.Dom.JsSubPath.endsWith("/")||(window.JsView.Dom.JsSubPath=window.JsView.Dom.JsSubPath+"/"),window.JsView.Dom.MainPathRef=document.location.href;let e=document.location.pathname.lastIndexOf(window.JsView.Dom.JsSubPath);window.JsView.Dom.MainPath=document.location.origin+document.location.pathname.substring(0,e)}e=window.JsView.Dom.MainPath+e.substring(1)}if(this.href=e,!t)return;let o=this.href,n=o.indexOf("#");n>0&&(this.hash=o.substring(n),o=o.substring(0,n));let r=o.indexOf("?");r>1&&(this.search=o.substring(r),o=o.substring(0,r));let s=o,a=s.indexOf("://");this.protocol=a>0?s.substring(0,a+1):"";let u=a>1?s.substring(a+3):"";a=u.indexOf("/"),this.host=a>0?u.substring(0,a):"",this.pathname=a>1?u.substring(a):"",this.origin=a>0?this.protocol+"//"+this.host:"",a=this.host.indexOf(":"),this.hostname=a>0?this.host.substring(0,a):this.host,this.port=a>1?this.host.substring(a+1):""}replace(e){this.href=e}href="";origin="";protocol="";host="";hostname="";port="";pathname="";search="";hash=""}class i{static SetBackgroundColor(t,o,n){const r=i.TextureManager.GetColorTextureCached(o);let s;n&&(s=new e.ViewRoundCornerMask(n.topLeft,n.topRight,n.bottomLeft,n.bottomRight));const a=new e.ExternalTextureSetting(r,s);t.ResetTexture(a)}static SetBackgroundImage(o,n,r,s,a,u,l){let d,h={};if("string"==typeof n){const e=new t(n);if(e instanceof t==!1)throw Error("Bad Argument.",e);h.url=e.href}else"linear-gradient"==n?.type&&(h.gradient=n);if(h.gradient)if(h.gradient.colors?.length>2){const e=h.gradient.colors,t=[e[0],e[e.length-1]],o=e.slice(1,e.length-1);d=i.TextureManager.CreateLinearGradientTexture(t,o)}else 2==h.gradient.colors?.length?d=i.TextureManager.CreateMiniGradientTexture(!0,h.gradient.colors[0],h.gradient.colors[1],h.gradient.rawValue):console.warn("Failed to create backgroundImage gradient, bad colors.",h.gradient.colors);else h.url&&(d=h.url.includes(".gif")||h.url.includes(".webp")?i.TextureManager.GetGifImage(h.url,!1,null,l):i.TextureManager.GetImage2(h.url,!1,a,u||e.ColorSpace.RGBA_8888));if(d){let t;r&&(t=new e.ViewRoundCornerMask(r.topLeft,r.topRight,r.bottomLeft,r.bottomRight));const i=new e.ExternalTextureSetting(d,t);if(o.ResetTexture(i),s){let e=d.RegisterLoadImageCallback(null,(function(){s({width:d.Width,height:d.Height})}));o.RegisterDetachCallback((()=>{d.UnregisterLoadImageCallback(e)}))}}}static SetMaskedBackgroundImage(o,n,r,s){if("string"==typeof n&&(n=new t(n)),n instanceof t==!1)throw Error("Bad Argument.",n);if("string"==typeof r&&(r=new t(r)),r instanceof t==!1)throw Error("Bad Argument(MaskURL).",r);const a=i.TextureManager.GetImage2(n.href,!1,null,s||e.ColorSpace.RGBA_8888);if(a){const t=i.TextureManager.GetImage2(r.href,!1,null,e.ColorSpace.RGBA_8888),n=new e.ExternalTextureSetting(a,new e.ViewTextureMask(t));o.ResetTexture(n)}}static SetVideoTexture(t,o,n){const r=i.TextureManager.GetColorTexture(o);let s;n&&(s=new e.ViewRoundCornerMask(n.topLeft,n.topRight,n.bottomLeft,n.bottomRight));const a=new e.TextureSetting(r,s);t.ResetTexture(a)}static GetTextWidth(t){return t.str||(t.str=""),t.font||(t.font=e.TextUtils._sDefaultFont),t.size||(t.size=e.TextUtils._sDefaultFontSize),"italic"!==t.italic&&(t.italic=""),"bold"!==t.bold&&(t.bold=""),window.PlatformUtils.GetTextWidth(t)}static RequestSwap(){e.sRenderBridge.RequestSwap()}static SetImgTexSize(e,t){let o={size:t,refNum:0};i.TextureInfo.Cache[e.Source]=o}static RefImgTexSize(e,t){let o=i.TextureInfo.Cache[e.Source];o?(o.refNum>0?o.refNum++:o.refNum=1,t(o.size)):e.RegisterLoadImageCallback(null,(function(){const o={width:e.Width,height:e.Height};t(o);let n=i.TextureInfo.Cache[e.Source];if(n)n.refNum>0?n.refNum++:n.refNum=1;else{let t={size:o,refNum:1};i.TextureInfo.Cache[e.Source]=t}}))}static UnrefImgTexSize(e){if(!e)return;let t=i.TextureInfo.Cache[e.Source];t&&(t.refNum--,t.refNum<=0&&i.TextureInfo.Unused.add(e.Source))}static ClearUnusedTexSize(){for(let e of i.TextureInfo.Unused){let t=i.TextureInfo.Cache[e];t.refNum<-2?(delete i.TextureInfo.Cache[e],i.TextureInfo.Unused.delete(e)):t.refNum<=0?t.refNum--:i.TextureInfo.Unused.delete(e)}}}i.TextureInfo={Cache:{},Unused:new Set},i.TextureManager=null,i.RootView=null,i.RootActivity=null,i.HaltKeyEvent=!1,window.JsvCode.ForgeExtension||(window.JsvCode.ForgeExtension=i);var o=i=window.JsvCode.ForgeExtension;export{e as Forge,o as ForgeExtension};
|
package/dom/index.mjs
CHANGED
|
@@ -5,10 +5,10 @@ function getCodeDebugConfig() {
|
|
|
5
5
|
// TODO: 进行编译(yarn build)时,需要设置为fasle。
|
|
6
6
|
enableDebug: false,
|
|
7
7
|
|
|
8
|
-
domBrowserPath: './code/src/dom-
|
|
9
|
-
domNativePath: './code/src/dom-
|
|
10
|
-
engineBrowserPath: './code/src/engine-js/browser/index.
|
|
11
|
-
forgeDefinePath: './code/src/engine-js/index.
|
|
8
|
+
domBrowserPath: './code/src/dom-2.0/dom-env/browser/index.ts',
|
|
9
|
+
domNativePath: './code/src/dom-2.0/dom-env/native/index.ts',
|
|
10
|
+
engineBrowserPath: './code/src/dom-2.0/engine-js/browser/index.ts',
|
|
11
|
+
forgeDefinePath: './code/src/dom-2.0/engine-js/index.ts',
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
return codeDebug;
|
|
@@ -19,7 +19,7 @@ async function loadJsViewDomNative(codeDebugConfig)
|
|
|
19
19
|
let domNative = null;
|
|
20
20
|
|
|
21
21
|
if (codeDebugConfig.enableDebug == false) {
|
|
22
|
-
domNative = await import('./bin/jsview-dom.min.js');
|
|
22
|
+
domNative = await import('./bin/jsview-dom-native.min.js');
|
|
23
23
|
} else {
|
|
24
24
|
// 兼容webpack写法
|
|
25
25
|
domNative = await import(
|
|
@@ -45,17 +45,18 @@ async function loadJsViewDomBrowserDebug(codeDebugConfig)
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// 加载jsv-dom的调试版本
|
|
48
|
+
let domBrowser = null;
|
|
48
49
|
if (codeDebugConfig.enableDebug == false) {
|
|
49
|
-
await import('./bin/jsview-browser
|
|
50
|
+
domBrowser = await import('./bin/jsview-dom-browser.min.js');
|
|
50
51
|
} else {
|
|
51
52
|
// 兼容webpack写法
|
|
52
|
-
await import(
|
|
53
|
+
domBrowser = await import(
|
|
53
54
|
/* webpackExclude: /@shijiu\/jsview\/dom\/code\/node_modules\// */
|
|
54
55
|
`${codeDebugConfig.domBrowserPath}`
|
|
55
56
|
);
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
return
|
|
59
|
+
return domBrowser;
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
async function getForgeDefineAsync() {
|
|
@@ -89,6 +90,8 @@ async function loadJsViewDomAsync(nativeOrBrowserDebug)
|
|
|
89
90
|
if (nativeOrBrowserDebug) {
|
|
90
91
|
jsviewDom = await loadJsViewDomNative(codeDebugConfig);
|
|
91
92
|
} else {
|
|
93
|
+
window.JsvCode = {}; // native 在java中定义
|
|
94
|
+
|
|
92
95
|
jsviewDom = await loadJsViewDomBrowserDebug(codeDebugConfig);
|
|
93
96
|
}
|
|
94
97
|
|
package/loader/jsview-loader.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import JsViewDefConfig from "./jsview.config.default"
|
|
2
|
-
import JsViewBrowserForgeApp from './jsview-browser-forgeapp'
|
|
3
2
|
import { loadJsViewDomAsync } from '../dom'
|
|
4
3
|
import TargetRevision from "../dom/target_core_revision"
|
|
5
4
|
|
|
@@ -27,13 +26,15 @@ export default class JsViewLoader {
|
|
|
27
26
|
const jsviewDom = await loadJsViewDomAsync(window.JsView);
|
|
28
27
|
|
|
29
28
|
// 加载Forge
|
|
29
|
+
jsviewDom.InitEnv();
|
|
30
|
+
|
|
30
31
|
if (window.JsView) {
|
|
31
|
-
this.#forgeAppClass = jsviewDom.
|
|
32
|
+
this.#forgeAppClass = jsviewDom.NativeForgeApp;
|
|
32
33
|
|
|
33
34
|
// /static/js/: (可选配置)填写main.js或者bundle.js相对于index.html的相对位置,用于image/import.then的相对寻址
|
|
34
35
|
window.JsView.Dom.JsSubPath = this.#config.jsviewConfig.jsSubPath;
|
|
35
36
|
} else {
|
|
36
|
-
this.#forgeAppClass =
|
|
37
|
+
this.#forgeAppClass = jsviewDom.BrowserForgeApp;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
this.#loadJsViewEnvAsync(appName, onLoaded);
|
|
@@ -103,7 +104,7 @@ export default class JsViewLoader {
|
|
|
103
104
|
onLoaded()
|
|
104
105
|
};
|
|
105
106
|
} else {
|
|
106
|
-
|
|
107
|
+
this.#forgeAppClass.SetRender(function () {
|
|
107
108
|
onLoaded();
|
|
108
109
|
})
|
|
109
110
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shijiu/jsview",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.912",
|
|
4
4
|
"bin": {
|
|
5
5
|
"jsview-post-build": "./tools/jsview-post-build.js",
|
|
6
6
|
"jsview-post-install": "./tools/jsview-post-install.js"
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"gifuct-js": "2.1.2",
|
|
20
|
-
"postcss-import-sync": "7.1.4",
|
|
21
20
|
"postcss-js": "4.0.0"
|
|
22
21
|
},
|
|
23
22
|
"devDependencies": {},
|
|
@@ -17669,14 +17669,24 @@ function doCompileStyle(options) {
|
|
|
17669
17669
|
// In async mode, return a promise.
|
|
17670
17670
|
if (options.isAsync) {
|
|
17671
17671
|
return result
|
|
17672
|
-
|
|
17672
|
+
// JsView Modified >>>
|
|
17673
|
+
// CSS文件异步变动时触发文件更新
|
|
17674
|
+
// .then(result => ({
|
|
17675
|
+
.then(result => {
|
|
17676
|
+
jsvCssToJs.compileAndSaveImportedNode(filename, result.root.nodes)
|
|
17677
|
+
return {
|
|
17678
|
+
// JsView Modified <<<
|
|
17673
17679
|
code: result.css || '',
|
|
17674
17680
|
map: result.map && result.map.toJSON(),
|
|
17675
17681
|
errors,
|
|
17676
17682
|
modules: cssModules,
|
|
17677
17683
|
rawResult: result,
|
|
17678
17684
|
dependencies: recordPlainCssDependencies(result.messages)
|
|
17679
|
-
|
|
17685
|
+
// JsView Modified >>>
|
|
17686
|
+
// CSS文件异步变动时触发文件更新
|
|
17687
|
+
// }))
|
|
17688
|
+
}})
|
|
17689
|
+
// JsView Modified <<<
|
|
17680
17690
|
.catch(error => ({
|
|
17681
17691
|
code: '',
|
|
17682
17692
|
map: undefined,
|
|
@@ -17689,6 +17699,11 @@ function doCompileStyle(options) {
|
|
|
17689
17699
|
// force synchronous transform (we know we only have sync plugins)
|
|
17690
17700
|
code = result.css;
|
|
17691
17701
|
outMap = result.map;
|
|
17702
|
+
|
|
17703
|
+
// JsView Added >>>
|
|
17704
|
+
// CSS文件同步变动时触发文件更新
|
|
17705
|
+
jsvCssToJs.compileAndSaveImportedNode(filename, result.result.root.nodes)
|
|
17706
|
+
// JsView Added <<<
|
|
17692
17707
|
}
|
|
17693
17708
|
catch (e) {
|
|
17694
17709
|
errors.push(e);
|
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
/*
|
|
2
|
-
*
|
|
2
|
+
* QCode Added
|
|
3
3
|
*/
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
6
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
7
7
|
|
|
8
8
|
const crypto = require('crypto');
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
var postCssJs = require('postcss-js');
|
|
13
|
-
var postCssImport = require('postcss-import-sync');
|
|
14
|
-
const compilerSfc = require("./compiler-sfc.cjs");
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const postCssJs = require('postcss-js');
|
|
15
12
|
const styleFormat = require("./jsview-style-format");
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
var cachedCssStyles = {}
|
|
14
|
+
const cachedCssStyles = {};
|
|
19
15
|
|
|
20
16
|
function ensureSfcDescriptor(descriptor) {
|
|
21
17
|
try {
|
|
@@ -27,7 +23,9 @@ function ensureSfcDescriptor(descriptor) {
|
|
|
27
23
|
|
|
28
24
|
function compileCssToJs(sfc, options) {
|
|
29
25
|
try {
|
|
30
|
-
|
|
26
|
+
const styleJsFilePath = getStyleJsFilePath(sfc.filename);
|
|
27
|
+
return `\nimport "${styleJsFilePath}";`
|
|
28
|
+
// return compileCssToJsImpl(sfc, options)
|
|
31
29
|
} catch (exception) {
|
|
32
30
|
console.error("Failed to call compileCssToJs()! Exception:\n", exception);
|
|
33
31
|
}
|
|
@@ -77,96 +75,6 @@ function ensureSfcDescriptorImpl(descriptor) {
|
|
|
77
75
|
};
|
|
78
76
|
}
|
|
79
77
|
|
|
80
|
-
function compileCssToJsImpl(sfc, options) {
|
|
81
|
-
if(sfc.styles.length <= 0) {
|
|
82
|
-
return ""
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
let compileStyleOptions = {
|
|
86
|
-
filename: sfc.filename,
|
|
87
|
-
id: `data-v-${options.id}`,
|
|
88
|
-
// map: null,
|
|
89
|
-
trim: true,
|
|
90
|
-
isProd: options.isProd,
|
|
91
|
-
|
|
92
|
-
source: null,
|
|
93
|
-
scoped: false,
|
|
94
|
-
modules: false,
|
|
95
|
-
};
|
|
96
|
-
// let styleCodeContainer = new Set();
|
|
97
|
-
let styleContentContainer = "";
|
|
98
|
-
let styleImportContainer = "";
|
|
99
|
-
sfc.styles.forEach(style => {
|
|
100
|
-
if(!!style.module) {
|
|
101
|
-
let errMsg = "JsView: style module is not released by Vue3!\n";
|
|
102
|
-
errMsg += style;
|
|
103
|
-
console.error(errMsg + " errors =", errors);
|
|
104
|
-
throw new Error(errMsg)
|
|
105
|
-
}
|
|
106
|
-
compileStyleOptions.source = style.content
|
|
107
|
-
if(!!style.attrs.src) { // 处理<style [scoped] src="xxx">
|
|
108
|
-
const baseDir = path.dirname(sfc.filename);
|
|
109
|
-
const cssSrcPath = path.resolve(baseDir, style.attrs.src);
|
|
110
|
-
compileStyleOptions.source = fs.readFileSync(cssSrcPath, "utf8");
|
|
111
|
-
}
|
|
112
|
-
compileStyleOptions.scoped = style.scoped
|
|
113
|
-
compileStyleOptions.modules = style.module
|
|
114
|
-
const { rawResult, errors } = compilerSfc.compileStyle(compileStyleOptions)
|
|
115
|
-
if(errors.length) {
|
|
116
|
-
const errMsg = "JsView: Failed to compile style when convert css to js!";
|
|
117
|
-
console.error(errMsg + " errors =", errors);
|
|
118
|
-
throw new Error(errMsg)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const styleNodes = rawResult.result.root.nodes;
|
|
122
|
-
styleNodes.forEach(node => {
|
|
123
|
-
// console.log('node=', node)
|
|
124
|
-
// console.log('node.type=', node.type, "node.name=", node.name, "node.selector=", node.selector);
|
|
125
|
-
|
|
126
|
-
if (node.type === "comment") {
|
|
127
|
-
// DO NOTHING
|
|
128
|
-
} else if(node.name === "import") {
|
|
129
|
-
const styleInfo = compileImportNode(node);
|
|
130
|
-
// styleCodeContainer.add(styleCode);
|
|
131
|
-
|
|
132
|
-
checkSelectors(node, styleInfo.styleFilePath, styleInfo.styleSelectors); // 检测selector是否已经处理过
|
|
133
|
-
let styleJsFilePath = path.relative(nodeModulesDir, styleInfo.styleJsFilePath);
|
|
134
|
-
styleJsFilePath = styleJsFilePath.replace(/\\/g, '/');
|
|
135
|
-
styleImportContainer += `\nimport "/${path.basename(nodeModulesDir)}/${styleJsFilePath}";`
|
|
136
|
-
} else if(node.name === "keyframes") {
|
|
137
|
-
const styleFilePath = node.source.input.file;
|
|
138
|
-
const styleSelectors = new Set([node.params]);
|
|
139
|
-
const styleContent = compileKeyframesNode(node);
|
|
140
|
-
|
|
141
|
-
checkSelectors(node, styleFilePath, styleSelectors); // 检测selector是否已经处理过
|
|
142
|
-
styleContentContainer += styleContent;
|
|
143
|
-
} else if(!!node.selector) {
|
|
144
|
-
const styleFilePath = node.source.input.file;
|
|
145
|
-
const styleSelectors = new Set([node.selector]);
|
|
146
|
-
const styleContent = compileSelectorNode(node);
|
|
147
|
-
|
|
148
|
-
checkSelectors(node, styleFilePath, styleSelectors); // 检测selector是否已经处理过
|
|
149
|
-
styleContentContainer += styleContent;
|
|
150
|
-
} else {
|
|
151
|
-
check(false, node.source.input.css, "JsView Error: Unsupported css node.");
|
|
152
|
-
}
|
|
153
|
-
})
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
let jsvStyleSheets = styleImportContainer;
|
|
157
|
-
jsvStyleSheets += "\nObject.assign(window.JsvCode.Dom.StyleSheets, {";
|
|
158
|
-
jsvStyleSheets += styleContentContainer;
|
|
159
|
-
jsvStyleSheets += "});\n";
|
|
160
|
-
|
|
161
|
-
// 用于@import的css hotload,但是没有生效
|
|
162
|
-
// styleCodeContainer.forEach(styleCode => {
|
|
163
|
-
// jsvStyleSheets += styleCode + "\n";
|
|
164
|
-
// });
|
|
165
|
-
|
|
166
|
-
// console.log('jsview-css-to-js.compileCssToJs() jsvStyleSheets=' + jsvStyleSheets)
|
|
167
|
-
return jsvStyleSheets;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
78
|
function checkSelectors(node, styleFilePath, styleSelectors) {
|
|
171
79
|
for(let cachedFilePath in cachedCssStyles) {
|
|
172
80
|
if(cachedFilePath == styleFilePath) {
|
|
@@ -176,9 +84,12 @@ function checkSelectors(node, styleFilePath, styleSelectors) {
|
|
|
176
84
|
const cachedSelectors = cachedCssStyles[cachedFilePath];
|
|
177
85
|
for(let selector of cachedSelectors) {
|
|
178
86
|
if(styleSelectors.has(selector)) { // 发现重复的selector
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
87
|
+
if (selector.includes['['] && selector.includes[']']) { // scoped style
|
|
88
|
+
let errMsg = "JsView Warn: Multi defined CSS selector '" + selector + "' from " + node.source.input.file + ".\n";
|
|
89
|
+
errMsg += "It has been defined in " + cachedFilePath + ".\n";
|
|
90
|
+
console.warn(errMsg);
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
182
93
|
}
|
|
183
94
|
}
|
|
184
95
|
}
|
|
@@ -190,79 +101,148 @@ function checkSelectors(node, styleFilePath, styleSelectors) {
|
|
|
190
101
|
}
|
|
191
102
|
cachedSelectors = new Set([...cachedSelectors, ...styleSelectors]);
|
|
192
103
|
cachedCssStyles[styleFilePath] = cachedSelectors;
|
|
104
|
+
|
|
105
|
+
return true;
|
|
193
106
|
}
|
|
194
107
|
|
|
195
108
|
function check(expr, source, errMsg) {
|
|
196
109
|
if(!expr) {
|
|
197
|
-
errMsg += (" source is: \n" + source);
|
|
198
|
-
console.error(
|
|
110
|
+
errMsg += ("\n source is: \n" + source);
|
|
111
|
+
console.error(errMsg);
|
|
199
112
|
throw new Error(errMsg);
|
|
200
113
|
}
|
|
201
114
|
}
|
|
202
115
|
|
|
203
|
-
function
|
|
204
|
-
const
|
|
205
|
-
|
|
116
|
+
function compileAndSaveImportedNodeImpl(styleFilePath, styleNodes) {
|
|
117
|
+
const { styleImports, styleSheets } = deserializeStyleJsFile(styleFilePath);
|
|
118
|
+
|
|
119
|
+
styleNodes.forEach(node => {
|
|
120
|
+
if (node.type === "comment"
|
|
121
|
+
|| node.name === "-webkit-keyframes"
|
|
122
|
+
|| node.name === "charset") {
|
|
123
|
+
// DO NOTHING
|
|
124
|
+
} else if(node.name === "import") {
|
|
125
|
+
const importContent = compileImportNode(node);
|
|
126
|
+
if (styleImports.includes(importContent) == false) {
|
|
127
|
+
styleImports.push(importContent);
|
|
128
|
+
}
|
|
129
|
+
} else if(node.name === "keyframes") {
|
|
130
|
+
const styleFilePath = node.source.input.file;
|
|
131
|
+
const styleSelectors = new Set([node.params]);
|
|
132
|
+
const checked = checkSelectors(node, styleFilePath, styleSelectors); // 检测selector是否已经处理过
|
|
133
|
+
if (checked == false) {
|
|
134
|
+
// 已经处理过,直接返回了,优化@import被展开问题。
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
206
137
|
|
|
207
|
-
|
|
138
|
+
const subStyleSheets = compileKeyframesNode(node);
|
|
139
|
+
for (const [scopedId, styleRules] of Object.entries(subStyleSheets)) {
|
|
140
|
+
styleSheets[scopedId] = Object.assign(styleSheets[scopedId] ?? {}, styleRules);
|
|
141
|
+
}
|
|
142
|
+
} else if(!!node.selector) {
|
|
143
|
+
const styleFilePath = node.source.input.file;
|
|
144
|
+
const styleSelectors = new Set([node.selector]);
|
|
145
|
+
const checked = checkSelectors(node, styleFilePath, styleSelectors); // 检测selector是否已经处理过
|
|
146
|
+
if (checked == false) {
|
|
147
|
+
// 已经处理过,直接返回了,优化@import被展开问题。
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
208
150
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
151
|
+
const subStyleSheets = compileSelectorNode(node);
|
|
152
|
+
for (const [scopedId, styleRules] of Object.entries(subStyleSheets)) {
|
|
153
|
+
const mergedStyleRules = styleSheets[scopedId] ?? {};
|
|
154
|
+
for (const [selector, declarations] of Object.entries(styleRules)) {
|
|
155
|
+
let mergedDeclarations = mergedStyleRules[selector] ?? '{}';
|
|
156
|
+
mergedDeclarations = Object.assign(JSON.parse(mergedDeclarations), JSON.parse(declarations));
|
|
157
|
+
mergedStyleRules[selector] = JSON.stringify(mergedDeclarations);
|
|
158
|
+
}
|
|
159
|
+
styleSheets[scopedId] = mergedStyleRules;
|
|
160
|
+
}
|
|
161
|
+
styleSelectors.add(node.selector);
|
|
162
|
+
} else if (node.name === "-moz-keyframes"
|
|
163
|
+
|| node.name === "-o-keyframes"
|
|
164
|
+
|| node.name === "-webkit-keyframes") {
|
|
165
|
+
// Stylus 添加的keyframes,忽略,只处理@keyframes
|
|
166
|
+
} else {
|
|
167
|
+
console.log("Unsupported css node: ", node);
|
|
168
|
+
check(false, node.source.input.css, "JsView Error: Unsupported css node from import css file.");
|
|
169
|
+
}
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
// console.log('jsview-css-to-js.compileAndSaveImportedNodeImpl() styleFilePath=', styleFilePath, ', styleSheets=', styleSheets);
|
|
173
|
+
serializeStyleJsFile(styleFilePath, { styleImports, styleSheets });
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function deserializeStyleJsFile(styleFilePath) {
|
|
177
|
+
const styleJsFilePath = getStyleJsFilePath(styleFilePath);
|
|
213
178
|
|
|
214
|
-
|
|
215
|
-
|
|
179
|
+
let styleImports = [];
|
|
180
|
+
let styleSheets = {};
|
|
216
181
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
182
|
+
let styleJsContent = fs.readFileSync(styleJsFilePath, "utf8");
|
|
183
|
+
if (styleJsContent) {
|
|
184
|
+
const styleSheetsFlags = getStyleSheetsDeclaredFlags();
|
|
185
|
+
const styleImportsContent = styleJsContent.substring(0, styleJsContent.indexOf(styleSheetsFlags.start));
|
|
186
|
+
let styleSheetsContent = styleJsContent.substring(0, styleJsContent.indexOf(styleSheetsFlags.end));
|
|
187
|
+
styleSheetsContent = styleSheetsContent.substring(styleJsContent.indexOf(styleSheetsFlags.start) + styleSheetsFlags.start.length);
|
|
220
188
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
console.log('JsView Error: Failed to compile css import node.', e);
|
|
224
|
-
throw e;
|
|
189
|
+
styleImports = styleImportsContent.split('\n');
|
|
190
|
+
styleSheets = JSON.parse(styleSheetsContent.length != 0 ? styleSheetsContent : '{}');
|
|
225
191
|
}
|
|
226
192
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
styleImports,
|
|
196
|
+
styleSheets,
|
|
197
|
+
}
|
|
231
198
|
}
|
|
232
199
|
|
|
233
|
-
function
|
|
234
|
-
|
|
235
|
-
let styleContent = "";
|
|
200
|
+
function serializeStyleJsFile(styleFilePath, { styleImports, styleSheets }) {
|
|
201
|
+
const styleJsFilePath = getStyleJsFilePath(styleFilePath);
|
|
236
202
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
})
|
|
203
|
+
const styleSheetsFlags = getStyleSheetsDeclaredFlags();
|
|
204
|
+
const styleImportsContent = styleImports.join('\n');
|
|
205
|
+
const styleSheetsContent = JSON.stringify(styleSheets);
|
|
206
|
+
|
|
207
|
+
let styleJsContent = "";
|
|
208
|
+
styleJsContent += styleImportsContent;
|
|
209
|
+
styleJsContent += styleSheetsFlags.start;
|
|
210
|
+
styleJsContent += styleSheetsContent;
|
|
211
|
+
styleJsContent += styleSheetsFlags.end;
|
|
247
212
|
|
|
248
213
|
// 保存到js文件并import到script中
|
|
249
|
-
|
|
214
|
+
fs.writeFileSync(styleJsFilePath, styleJsContent, "utf8");
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function getStyleSheetsDeclaredFlags() {
|
|
218
|
+
return {
|
|
219
|
+
start: "\nconst styleSheetsContent = ",
|
|
220
|
+
end: ";\nwindow.JsvCode.Dom.DeclareStyleSheets(styleSheetsContent);",
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function getStyleJsCacheDir() {
|
|
225
|
+
const nodeModulesDir = path.resolve(process.cwd(), 'node_modules');
|
|
226
|
+
const cacheDir = path.resolve(nodeModulesDir, '@shijiu', '.cache', 'css-to-js'); // 不能放在.vite文件夹,否则有网络缓存,文件改变后不更新
|
|
250
227
|
if (!fs.existsSync(cacheDir)) {
|
|
251
|
-
fs.mkdirSync(cacheDir);
|
|
228
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
252
229
|
}
|
|
230
|
+
|
|
231
|
+
return cacheDir;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function getStyleJsFilePath(styleFilePath) {
|
|
235
|
+
// 保存到js文件并import到script中
|
|
236
|
+
const cacheDir = getStyleJsCacheDir()
|
|
237
|
+
|
|
253
238
|
const styleFilePathHash = crypto.createHash('md5').update(styleFilePath).digest('hex').substring(0, 8);
|
|
254
|
-
const styleJsFileName =
|
|
239
|
+
const styleJsFileName = styleFilePathHash + '.' + path.basename(styleFilePath) + '.js';
|
|
255
240
|
const styleJsFilePath = path.join(cacheDir, styleJsFileName);
|
|
241
|
+
if (!fs.existsSync(styleJsFilePath)) {
|
|
242
|
+
fs.closeSync(fs.openSync(styleJsFilePath, 'w'));
|
|
243
|
+
}
|
|
256
244
|
|
|
257
|
-
|
|
258
|
-
styleContent += "});\n";
|
|
259
|
-
fs.writeFileSync(styleJsFilePath, styleContent, "utf8");
|
|
260
|
-
|
|
261
|
-
return {
|
|
262
|
-
styleFilePath,
|
|
263
|
-
styleSelectors,
|
|
264
|
-
styleJsFilePath
|
|
265
|
-
};
|
|
245
|
+
return styleJsFilePath;
|
|
266
246
|
}
|
|
267
247
|
|
|
268
248
|
function getStringOffset(source, line, column) {
|
|
@@ -282,6 +262,15 @@ function getStringOffset(source, line, column) {
|
|
|
282
262
|
return offset;
|
|
283
263
|
}
|
|
284
264
|
|
|
265
|
+
function compileImportNode(node) {
|
|
266
|
+
const baseDir = path.dirname(node.source.input.file);
|
|
267
|
+
const cssFilePath = path.resolve(baseDir, node.params.replaceAll('"', ''));
|
|
268
|
+
const styleJsFilePath = getStyleJsFilePath(cssFilePath);
|
|
269
|
+
const styleImportContent = `\nimport "${styleJsFilePath}";`;
|
|
270
|
+
|
|
271
|
+
return styleImportContent;
|
|
272
|
+
}
|
|
273
|
+
|
|
285
274
|
function compileKeyframesNode(node) {
|
|
286
275
|
const name = node.name;
|
|
287
276
|
check(name, node.source.input.css, "JsView Error: name is not found!");
|
|
@@ -299,12 +288,17 @@ function compileKeyframesNode(node) {
|
|
|
299
288
|
const content = node.source.input.css.slice(startOffset, endOffset + 1);
|
|
300
289
|
// console.log('jsview-css-to-js.compileKeyframesNode() \n', startOffset, endOffset, content);
|
|
301
290
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
291
|
+
const kfName = node.params;
|
|
292
|
+
let kfValue = content.replace(/(\r|\n|\r\n)/g, " ");
|
|
293
|
+
kfValue = kfValue.replace(/@keyframes .*? {/g, "@keyframes " + kfName + " {");
|
|
294
|
+
|
|
295
|
+
const scopedId = '0'; // CSS规范中,keyframes没有继承, 放在glabol中
|
|
296
|
+
const kfRule = { [kfName]: kfValue };
|
|
305
297
|
|
|
306
|
-
|
|
307
|
-
|
|
298
|
+
const styleSheets = { [scopedId]: kfRule };
|
|
299
|
+
|
|
300
|
+
// console.log('jsview-css-to-js.compileKeyframesNode() return ', styleSheets);
|
|
301
|
+
return styleSheets;
|
|
308
302
|
}
|
|
309
303
|
|
|
310
304
|
function compileSelectorNode(node) {
|
|
@@ -316,20 +310,64 @@ function compileSelectorNode(node) {
|
|
|
316
310
|
check(selector.startsWith('.'), node.source.input.css, errMsg);
|
|
317
311
|
|
|
318
312
|
const declarations = postCssJs.objectify(node);
|
|
319
|
-
|
|
320
|
-
|
|
313
|
+
const styleSheets = parsePostCssJs(node, selector, declarations);
|
|
314
|
+
|
|
315
|
+
// console.log('jsview-css-to-js.compileSelectorNode() return ', styleSheets);
|
|
316
|
+
return styleSheets;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
function parsePostCssJs(node, selector, declarations) {
|
|
320
|
+
const styleSheets = { };
|
|
321
|
+
|
|
322
|
+
// 对 .a, .b {} 的支持
|
|
323
|
+
const selectorArray = selector.split(',');
|
|
324
|
+
for (let selector of selectorArray) {
|
|
325
|
+
selector = selector.trim();
|
|
326
|
+
|
|
327
|
+
let scopedId = selector.substring(selector.indexOf("[") + 1, selector.lastIndexOf("]"));
|
|
328
|
+
if (scopedId) {
|
|
329
|
+
selector = selector.substring(0, selector.indexOf("["));
|
|
330
|
+
scopedId = scopedId.replace('data-v-', '');
|
|
331
|
+
} else {
|
|
332
|
+
scopedId = '0';
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const styleRules = parseUnscopedStyleSheets(node, selector, declarations, scopedId);
|
|
336
|
+
|
|
337
|
+
let mergedStyleRules = styleSheets[scopedId] ?? {};
|
|
338
|
+
mergedStyleRules = Object.assign(mergedStyleRules, styleRules);
|
|
339
|
+
styleSheets[scopedId] = mergedStyleRules;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return styleSheets;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function parseUnscopedStyleSheets(node, selector, declarations, scopedId) {
|
|
346
|
+
let styleRules = {};
|
|
347
|
+
|
|
348
|
+
for (const [name, value] of Object.entries(declarations)) {
|
|
349
|
+
if (name.startsWith('@keyframes')) { // keyframes解嵌套处理
|
|
350
|
+
check(false, node.source.input.css, "JsView Error: Nested keyframes is not supported!");
|
|
351
|
+
delete declarations[name];
|
|
352
|
+
continue;
|
|
353
|
+
} else if (value instanceof Object) { // css class解嵌套处理
|
|
354
|
+
const unscopedName = name.replace('[data-v-' + scopedId + ']', '');
|
|
355
|
+
const nestedStyleSheets = parseUnscopedStyleSheets(node, selector + ' ' + unscopedName, value, scopedId);
|
|
356
|
+
styleRules = Object.assign(styleRules, nestedStyleSheets);
|
|
357
|
+
delete declarations[name];
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
|
|
321
361
|
const formattedValue = styleFormat.getFormattedValue(name, value);
|
|
322
362
|
declarations[name] = formattedValue;
|
|
323
363
|
}
|
|
324
364
|
|
|
325
|
-
|
|
326
|
-
styleContent += JSON.stringify(declarations);
|
|
327
|
-
styleContent += ",";
|
|
365
|
+
styleRules[selector] = JSON.stringify(declarations);
|
|
328
366
|
|
|
329
|
-
// console.log('jsview-css-to-js.
|
|
330
|
-
return
|
|
367
|
+
// console.log('jsview-css-to-js.parseUnscopedStyleSheets() return ', styleRules);
|
|
368
|
+
return styleRules;
|
|
331
369
|
}
|
|
332
370
|
|
|
333
371
|
exports.ensureSfcDescriptor = ensureSfcDescriptor;
|
|
334
372
|
exports.compileCssToJs = compileCssToJs;
|
|
335
|
-
exports.compileAndSaveImportedNode = compileAndSaveImportedNode;
|
|
373
|
+
exports.compileAndSaveImportedNode = compileAndSaveImportedNode;
|