@shijiu/jsview 1.9.887 → 1.9.909

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.
@@ -1 +1 @@
1
- /* eslint-disable */ void 0===window.Forge&&(window.Forge={});var e=window.Forge;class t{constructor(e,t){if(this.href="",this.origin="",this.protocol="",this.host="",this.hostname="",this.port="",this.pathname="",this.search="",this.hash="",!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("./")||!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)+"/"}let t=window.JsView.Dom.__MainPath;e=e.startsWith("./")?t+e.substring(2):t+e}if(this.href=e,!t)return;let n=this.href,r=n.indexOf("#");r>0&&(this.hash=n.substring(r),n=n.substring(0,r));let s=n.indexOf("?");s>1&&(this.search=n.substring(s),n=n.substring(0,s));let o=n,a=o.indexOf("://");this.protocol=a>0?o.substring(0,a+1):"";let u=a>1?o.substring(a+3):"";if(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:"",this.host.startsWith("[")){let e=this.host.indexOf("]");this.hostname=this.host.substring(0,e+1),e=this.host.substring(e+1).indexOf(":"),this.port=e>1?this.host.substring(e+1):""}else{let e=this.host.indexOf(":");this.hostname=e>0?this.host.substring(0,e):this.host,this.port=e>1?this.host.substring(e+1):""}}replace(e){this.href=e}}window.JsView&&window.JsView.registerUriConverter?.((e=>new t(e,!1).href));class i{static SetBackgroundColor(t,n,r){const s=i.TextureManager.GetColorTextureCached(n);let o;r&&(o=new e.ViewRoundCornerMask(r.topLeft,r.topRight,r.bottomLeft,r.bottomRight));const a=new e.ExternalTextureSetting(s,o);t.ResetTexture(a)}static SetBackgroundImage(n,r,s,o,a,u,h){let l,d={};if("string"==typeof r){const e=new t(r);if(e instanceof t==!1)throw Error("Bad Argument.",e);d.url=e.href}else"linear-gradient"==r?.type&&(d.gradient=r);if(d.gradient)if(d.gradient.colors?.length>2){const e=d.gradient.colors,t=[e[0],e[e.length-1]],n=e.slice(1,e.length-1);l=i.TextureManager.CreateLinearGradientTexture(t,n)}else 2==d.gradient.colors?.length?l=i.TextureManager.CreateMiniGradientTexture(!0,d.gradient.colors[0],d.gradient.colors[1],d.gradient.rawValue):console.warn("Failed to create backgroundImage gradient, bad colors.",d.gradient.colors);else d.url&&(l=d.url.includes(".gif")||d.url.includes(".webp")?i.TextureManager.GetGifImage(d.url,!1,null,h):i.TextureManager.GetImage2(d.url,!1,a,u||e.ColorSpace.RGBA_8888));if(l){let t;s&&(t=new e.ViewRoundCornerMask(s.topLeft,s.topRight,s.bottomLeft,s.bottomRight));const i=new e.ExternalTextureSetting(l,t);if(n.ResetTexture(i),o){let e=l.RegisterLoadImageCallback(null,(function(){o({width:l.Width,height:l.Height})}));n.RegisterDetachCallback((()=>{l.UnregisterLoadImageCallback(e)}))}}}static SetMaskedBackgroundImage(n,r,s,o){if("string"==typeof r&&(r=new t(r)),r instanceof t==!1)throw Error("Bad Argument.",r);if("string"==typeof s&&(s=new t(s)),s instanceof t==!1)throw Error("Bad Argument(MaskURL).",s);const a=i.TextureManager.GetImage2(r.href,!1,null,o||e.ColorSpace.RGBA_8888);if(a){const t=i.TextureManager.GetImage2(s.href,!1,null,e.ColorSpace.RGBA_8888),r=new e.ExternalTextureSetting(a,new e.ViewTextureMask(t));n.ResetTexture(r)}}static SetVideoTexture(t,n,r){const s=i.TextureManager.GetColorTexture(n);let o;r&&(o=new e.ViewRoundCornerMask(r.topLeft,r.topRight,r.bottomLeft,r.bottomRight));const a=new e.TextureSetting(s,o);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 n={size:t,refNum:0};i.TextureInfo.Cache[e.Source]=n}static RefImgTexSize(e,t){let n=i.TextureInfo.Cache[e.Source];n?(n.refNum>0?n.refNum++:n.refNum=1,t(n.size)):e.RegisterLoadImageCallback(null,(function(){const n={width:e.Width,height:e.Height};t(n);let r=i.TextureInfo.Cache[e.Source];if(r)r.refNum>0?r.refNum++:r.refNum=1;else{let t={size:n,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.JsView&&(window.JsView.ForgeExtension||(window.JsView.ForgeExtension=i),i=window.JsView.ForgeExtension);var n=i;export{e as Forge,n as ForgeExtension};
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-browser-hook/index.js',
9
- domNativePath: './code/src/dom-wrapper/index.js',
10
- engineBrowserPath: './code/src/engine-js/browser/index.js',
11
- forgeDefinePath: './code/src/engine-js/index.js',
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-debug-dom.min.js');
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 null;
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
 
@@ -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.JsViewForgeApp;
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 = JsViewBrowserForgeApp;
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
- JsViewBrowserForgeApp.setRender(function () {
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.887",
3
+ "version": "1.9.909",
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
- .then(result => ({
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
- * JsView Added
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
- var fs = require('fs');
10
- var path = require('path');
11
- var postCss = require('postcss');
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
- var nodeModulesDir = path.resolve(process.cwd(), 'node_modules')
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
- return compileCssToJsImpl(sfc, options)
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
- let errMsg = "JsView Warn: Multi defined CSS selector '" + selector + "' from " + node.source.input.file + ".\n";
180
- errMsg += "It has been defined in " + cachedFilePath + ".\n";
181
- check(false, node.source.input.css, errMsg);
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("\n" + errMsg);
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 compileImportNode(node) {
204
- const name = node.name;
205
- check(name, node.source.input.css, "JsView Error: name is not found!");
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
- check(name === "import", node.source.input.css, "JsView Error: @import name is not found!");
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
- let result = null;
210
- try {
211
- const plugins = [].slice();
212
- plugins.push(postCssImport)
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
- const content = node.source.input.css.slice(node.source.start.offset, node.source.end.offset + 1);
215
- check(content.endsWith(";"), "JsView Error: Failed to parse @import, please end with ';'")
179
+ let styleImports = [];
180
+ let styleSheets = {};
216
181
 
217
- const options = {
218
- from: node.source.input.file
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
- result = postCss(plugins).process(content, options);
222
- } catch (e) {
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
- const sourceDir = path.dirname(node.source.input.file);
228
- let styleFileName = node.params.replace(/^["'](.+(?=["']$))["']$/, '$1')
229
- const styleFilePath = path.resolve(sourceDir, styleFileName);
230
- return compileAndSaveImportedNodeImpl(styleFilePath, result.root.nodes);
193
+
194
+ return {
195
+ styleImports,
196
+ styleSheets,
197
+ }
231
198
  }
232
199
 
233
- function compileAndSaveImportedNodeImpl(styleFilePath, styleNodes) {
234
- let styleSelectors = new Set();
235
- let styleContent = "";
200
+ function serializeStyleJsFile(styleFilePath, { styleImports, styleSheets }) {
201
+ const styleJsFilePath = getStyleJsFilePath(styleFilePath);
236
202
 
237
- styleNodes.forEach(node => {
238
- if(node.name === "keyframes") {
239
- styleContent += compileKeyframesNode(node);
240
- } else if(!!node.selector) {
241
- styleContent += compileSelectorNode(node);
242
- styleSelectors.add(node.selector);
243
- } else {
244
- check(false, node.source.input.css, "JsView Error: Unsupported css node from import css file.");
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
- const cacheDir = path.resolve(nodeModulesDir, '@shijiu', '.cache')
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 = path.basename(styleFilePath) + '.' + styleFilePathHash + '.js';
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
- styleContent = "\nObject.assign(window.JsvCode.Dom.StyleSheets, {" + styleContent;
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
- let styleContent = "'" + node.params + "':'";
303
- styleContent += content.replace(/(\r|\n|\r\n)/g, " ");
304
- styleContent += "',";
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
- // console.log('jsview-css-to-js.compileKeyframesNode() return ' + styleContent);
307
- return styleContent
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
- for (const name in declarations) {
320
- const value = declarations[name];
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
- let styleContent = "'" + selector.substr(1) + "':";
326
- styleContent += JSON.stringify(declarations);
327
- styleContent += ",";
365
+ styleRules[selector] = JSON.stringify(declarations);
328
366
 
329
- // console.log('jsview-css-to-js.compileSelectorNode() return ', styleContent);
330
- return styleContent;
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;