Browse Source

upd: perf/feat

dongji136 3 years ago
parent
commit
fba61cfabd
1 changed files with 72 additions and 50 deletions
  1. 72 50
      src/sites/doc/components/ThemeSetting/helper.ts

+ 72 - 50
src/sites/doc/components/ThemeSetting/helper.ts

@@ -7,7 +7,7 @@ type Obj = {
 };
 };
 
 
 type Store = {
 type Store = {
-  rawVariables: Obj[];
+  variables: Obj[];
   variablesMap: Obj;
   variablesMap: Obj;
   rawStyles: Obj;
   rawStyles: Obj;
   [k: string]: any;
   [k: string]: any;
@@ -15,7 +15,7 @@ type Store = {
 
 
 const components = configs.nav.map(({ packages }) => packages.map(({ name }) => name)).flat(1);
 const components = configs.nav.map(({ packages }) => packages.map(({ name }) => name)).flat(1);
 
 
-const getGithubRawFile = async function (url: string) {
+const getRawFileText = async function (url: string) {
   const response = await fetch(url);
   const response = await fetch(url);
   const res = await response.text();
   const res = await response.text();
   return res;
   return res;
@@ -47,16 +47,8 @@ const awaitIframe = async () => {
   }
   }
 };
 };
 
 
-const cachedStyles: Obj = {};
-const store: Store = reactive({
-  init: false,
-  rawVariables: [],
-  variablesMap: {},
-  rawStyles: {}
-});
-
-// 提取变量,区分base和组件
-const extractVariable = (matched: string[], variables: string, name: string, lowerCaseName: string) =>
+// 提取变量
+const extractVariables = (matched: string[], name: string, lowerCaseName: string) =>
   matched.reduce((res, str) => {
   matched.reduce((res, str) => {
     const extract = str.replace(/\s+!default/, '').match(/(.*):(?:\s+)?([\s\S]*)(?:\s+)?;/);
     const extract = str.replace(/\s+!default/, '').match(/(.*):(?:\s+)?([\s\S]*)(?:\s+)?;/);
 
 
@@ -76,19 +68,33 @@ const extractVariable = (matched: string[], variables: string, name: string, low
     }
     }
     return res;
     return res;
   }, [] as Obj[]);
   }, [] as Obj[]);
-const getSassVariables = async (url: string) => {
-  if (Object.keys(store.rawVariables).length) {
-    return store;
+
+// 提取样式代码,只保留有使用变量的行
+const extractStyle = (style: string) => {
+  if (!store.variables.length) {
+    return '';
   }
   }
 
 
-  const variables = await getGithubRawFile(url);
+  const extract = style.split('\n').filter((str) => {
+    const matched = str.match(/\$[\w-]+\b/g);
+
+    if (matched) {
+      return matched.some((k) => store.variablesMap[k]);
+    }
+    return /(\{|\})/.test(str);
+  });
+
+  return extract.join('');
+};
+
+const parseSassVariables = (text: string, components: string[]) => {
   const matchedComponentVariables = components
   const matchedComponentVariables = components
     .map((name) => {
     .map((name) => {
       const lowerCaseName = name.toLowerCase();
       const lowerCaseName = name.toLowerCase();
       const reg = new RegExp(`(?<!\\/\\/(\\s+)?)\\$(${name}|${lowerCaseName})\\b[\\w-]+:[^:;]+;`, 'g');
       const reg = new RegExp(`(?<!\\/\\/(\\s+)?)\\$(${name}|${lowerCaseName})\\b[\\w-]+:[^:;]+;`, 'g');
-      const matched = variables.match(reg);
+      const matched = text.match(reg);
       if (matched) {
       if (matched) {
-        return extractVariable(matched, variables, name, lowerCaseName);
+        return extractVariables(matched, name, lowerCaseName);
       }
       }
     })
     })
     .filter(Boolean)
     .filter(Boolean)
@@ -101,42 +107,61 @@ const getSassVariables = async (url: string) => {
     'g'
     'g'
   );
   );
 
 
-  const rawVariables = matchedComponentVariables as Obj[];
+  const variables = matchedComponentVariables as Obj[];
 
 
-  const matchedBaseVariables = variables.match(baseVariablesReg);
+  const matchedBaseVariables = text.match(baseVariablesReg);
 
 
+  // 组件变量以外的都作为基础变量
   if (matchedBaseVariables) {
   if (matchedBaseVariables) {
-    rawVariables.unshift(...extractVariable(matchedBaseVariables, variables, 'Base', 'base'));
+    variables.unshift(...extractVariables(matchedBaseVariables, 'Base', 'base'));
+  }
+
+  return variables;
+};
+
+const cachedStyles: Obj = {};
+const store: Store = reactive({
+  init: false,
+  variables: [],
+  variablesMap: {},
+  rawStyles: {}
+});
+
+const getSassVariables = async () => {
+  const rawVariablesText = await getRawFileText(
+    '/devRaw/jd-platform-opensource/nutui/raw/next/src/packages/styles/variables.scss'
+  );
+  const rawVariables = parseSassVariables(rawVariablesText, components);
+
+  // 固定自定义主题的访问链接: https://nutui.jd.com/theme/?theme=自定义变量的文件地址#/
+  // e.g. https://nutui.jd.com/theme/?theme=xxx.com%2variables.scss#/
+  // vite issue https://github.com/vitejs/vite/issues/6894
+  const params = new URLSearchParams(window.location.search);
+  const customUrl = params.get('theme');
+  if (customUrl) {
+    const customVariablesText = await getRawFileText(customUrl);
+    const customVariables = parseSassVariables(customVariablesText, components);
+
+    // merge
+    rawVariables.forEach((item) => {
+      const custom = customVariables.find(({ key }) => key === item.key);
+      if (custom) {
+        item.value = custom.value;
+      }
+    });
   }
   }
 
 
   const variablesMap = rawVariables.reduce((map, item) => {
   const variablesMap = rawVariables.reduce((map, item) => {
     map[item.key] = 1;
     map[item.key] = 1;
     return map;
     return map;
   }, {});
   }, {});
-  store.rawVariables = rawVariables;
+  store.variables = rawVariables;
   store.variablesMap = variablesMap;
   store.variablesMap = variablesMap;
 };
 };
 
 
-// 提取样式代码,只保留有使用变量的行
-const extractStyle = (style: string) => {
-  if (!store.rawVariables.length) {
-    return '';
-  }
-
-  const extract = style.split('\n').filter((str) => {
-    const matched = str.match(/\$[\w-]+\b/g);
-
-    if (matched) {
-      return matched.some((k) => store.variablesMap[k]);
-    }
-    return /(\{|\})/.test(str);
-  });
-
-  return extract.join('');
-};
-export const getSassStyle = async (name: string): Promise<void> => {
+export const getRawSassStyle = async (name: string): Promise<void> => {
   if (!store.rawStyles[name]) {
   if (!store.rawStyles[name]) {
-    const style = await getGithubRawFile(
+    const style = await getRawFileText(
       `/devRaw/jd-platform-opensource/nutui/raw/next/src/packages/__VUE/${name}/index.scss`
       `/devRaw/jd-platform-opensource/nutui/raw/next/src/packages/__VUE/${name}/index.scss`
     );
     );
     store.rawStyles[name] = style;
     store.rawStyles[name] = style;
@@ -147,7 +172,7 @@ export const useThemeEditor = function (): Obj {
   const route = useRoute();
   const route = useRoute();
 
 
   const cssText = computed(() => {
   const cssText = computed(() => {
-    const variablesText = store.rawVariables.map(({ key, value }) => `${key}:${value}`).join(';');
+    const variablesText = store.variables.map(({ key, value }) => `${key}:${value}`).join(';');
 
 
     const styleText = Object.keys(store.rawStyles)
     const styleText = Object.keys(store.rawStyles)
       .map((name) => {
       .map((name) => {
@@ -162,15 +187,12 @@ export const useThemeEditor = function (): Obj {
   const formItems = computed(() => {
   const formItems = computed(() => {
     const name = route.path.substring(1);
     const name = route.path.substring(1);
 
 
-    return store.rawVariables.filter(({ lowerCaseName }) => lowerCaseName === name);
+    return store.variables.filter(({ lowerCaseName }) => lowerCaseName === name);
   });
   });
 
 
   onMounted(async () => {
   onMounted(async () => {
     if (!store.init) {
     if (!store.init) {
-      await Promise.all([
-        getSassVariables('/devRaw/jd-platform-opensource/nutui/raw/next/src/packages/styles/variables.scss'),
-        loadScript('https://cdnout.com/sass.js/sass.sync.min.js')
-      ]);
+      await Promise.all([getSassVariables(), loadScript('https://cdnout.com/sass.js/sass.sync.min.js')]);
       store.init = true;
       store.init = true;
     }
     }
   });
   });
@@ -180,7 +202,7 @@ export const useThemeEditor = function (): Obj {
     (path) => {
     (path) => {
       const name = path.substring(1);
       const name = path.substring(1);
       if (name !== 'base') {
       if (name !== 'base') {
-        getSassStyle(name);
+        getRawSassStyle(name);
       }
       }
     },
     },
     {
     {
@@ -220,12 +242,12 @@ export const useThemeEditor = function (): Obj {
   return {
   return {
     formItems,
     formItems,
     downloadScssVariables() {
     downloadScssVariables() {
-      if (!store.rawVariables.length) {
+      if (!store.variables.length) {
         return;
         return;
       }
       }
 
 
       let temp = '';
       let temp = '';
-      const variablesText = store.rawVariables
+      const variablesText = store.variables
         .map(({ name, key, value }) => {
         .map(({ name, key, value }) => {
           let comment = '';
           let comment = '';
           if (temp !== name) {
           if (temp !== name) {