提交 6212b4ef 作者: 方治民

合并分支 '3.x' 到 'main'

3.x

查看合并请求 !73
......@@ -66,29 +66,29 @@
}
},
"dependencies": {
"@dcloudio/uni-app": "3.0.0-4020920240930001",
"@dcloudio/uni-app-plus": "3.0.0-4020920240930001",
"@dcloudio/uni-components": "3.0.0-4020920240930001",
"@dcloudio/uni-h5": "3.0.0-4020920240930001",
"@dcloudio/uni-mp-alipay": "3.0.0-4020920240930001",
"@dcloudio/uni-mp-baidu": "3.0.0-4020920240930001",
"@dcloudio/uni-mp-jd": "3.0.0-4020920240930001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-4020920240930001",
"@dcloudio/uni-mp-lark": "3.0.0-4020920240930001",
"@dcloudio/uni-mp-qq": "3.0.0-4020920240930001",
"@dcloudio/uni-mp-toutiao": "3.0.0-4020920240930001",
"@dcloudio/uni-mp-weixin": "3.0.0-4020920240930001",
"@dcloudio/uni-quickapp-webview": "3.0.0-4020920240930001",
"@dcloudio/uni-ui": "^1.5.6",
"@dcloudio/uni-app": "3.0.0-4030620241128001",
"@dcloudio/uni-app-plus": "3.0.0-4030620241128001",
"@dcloudio/uni-components": "3.0.0-4030620241128001",
"@dcloudio/uni-h5": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-alipay": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-baidu": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-jd": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-lark": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-qq": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-toutiao": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-weixin": "3.0.0-4030620241128001",
"@dcloudio/uni-quickapp-webview": "3.0.0-4030620241128001",
"@dcloudio/uni-ui": "^1.5.7",
"@faker-js/faker": "^8.4.1",
"@vue/runtime-core": "3.4.21",
"@vueuse/core": "^10.11.1",
"@vueuse/shared": "^11.1.0",
"axios": "^1.7.7",
"@vueuse/core": "^12.2.0",
"@vueuse/shared": "^12.2.0",
"axios": "^1.7.9",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.13",
"lodash-es": "^4.17.21",
"nanoid": "^5.0.7",
"nanoid": "^5.0.9",
"pinia": "2.0.36",
"qs": "6.9.7",
"stompjs": "^2.3.3",
......@@ -101,20 +101,20 @@
},
"devDependencies": {
"@antfu/eslint-config": "^0.43.1",
"@commitlint/cli": "^19.5.0",
"@commitlint/config-conventional": "^19.5.0",
"@commitlint/cli": "^19.6.1",
"@commitlint/config-conventional": "^19.6.0",
"@dcloudio/types": "^3.4.14",
"@dcloudio/uni-automator": "3.0.0-4020920240930001",
"@dcloudio/uni-cli-shared": "3.0.0-4020920240930001",
"@dcloudio/uni-automator": "3.0.0-4030620241128001",
"@dcloudio/uni-cli-shared": "3.0.0-4030620241128001",
"@dcloudio/uni-helper-json": "^1.0.13",
"@dcloudio/uni-stacktracey": "3.0.0-4020920240930001",
"@dcloudio/uni-uts-v1": "3.0.0-4020920240930001",
"@dcloudio/vite-plugin-uni": "3.0.0-4020920240930001",
"@iconify/json": "^2.2.262",
"@dcloudio/uni-stacktracey": "3.0.0-4030620241128001",
"@dcloudio/uni-uts-v1": "3.0.0-4030620241128001",
"@dcloudio/vite-plugin-uni": "3.0.0-4030620241128001",
"@iconify/json": "^2.2.290",
"@types/crypto-js": "^4.2.2",
"@types/lodash-es": "^4.17.12",
"@types/node": "^20.16.13",
"@types/qs": "^6.9.16",
"@types/node": "^22.10.2",
"@types/qs": "^6.9.17",
"@types/stompjs": "^2.3.9",
"@types/urijs": "^1.19.25",
"@typescript-eslint/eslint-plugin": "^7.18.0",
......@@ -122,30 +122,30 @@
"commitizen": "^4.3.1",
"conventional-changelog-cli": "^5.0.0",
"cz-conventional-changelog": "^3.3.0",
"cz-customizable": "^7.2.1",
"cz-git": "^1.10.1",
"czg": "^1.10.1",
"dotenv": "^16.4.5",
"cz-customizable": "^7.4.0",
"cz-git": "^1.11.0",
"czg": "^1.11.0",
"dotenv": "^16.4.7",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-vue": "^9.29.1",
"eslint-plugin-vue": "^9.32.0",
"husky": "^8.0.3",
"jest": "27.0.4",
"jest-environment-node": "27.5.1",
"less": "^4.2.0",
"lint-staged": "^15.2.10",
"less": "^4.2.1",
"lint-staged": "^15.3.0",
"npm-run-all": "^4.1.5",
"picocolors": "^1.1.1",
"pont-engine": "^1.6.3",
"postcss": "^8.4.47",
"postcss": "^8.4.49",
"postcss-html": "^1.7.0",
"postcss-less": "^6.0.0",
"prettier": "^3.3.3",
"prettier": "^3.4.2",
"rimraf": "^6.0.1",
"sass": "^1.80.3",
"sort-package-json": "^2.10.1",
"stylelint": "^16.10.0",
"sass": "^1.83.0",
"sort-package-json": "^2.12.0",
"stylelint": "^16.12.0",
"stylelint-config-html": "^1.1.0",
"stylelint-config-recommended": "^14.0.1",
"stylelint-config-standard": "^36.0.1",
......@@ -154,8 +154,8 @@
"unocss": "^0.58.9",
"unocss-preset-weapp": "^0.58.8",
"unplugin-auto-import": "^0.17.8",
"unplugin-vue-components": "^0.27.4",
"vite": "^5.4.9",
"unplugin-vue-components": "^0.28.0",
"vite": "^5.4.11",
"vue-eslint-parser": "^9.4.3"
},
"engines": {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -130,14 +130,15 @@
.fui-footer__fixed-bottom {
position: fixed;
z-index: 99;
bottom: 0;
left: 0;
right: 0;
/* #ifndef APP-NVUE */
left: constant(safe-area-inset-left);
/* left: constant(safe-area-inset-left);
left: env(safe-area-inset-left);
right: constant(safe-area-inset-right);
right: env(safe-area-inset-right)
/* #endif */
right: env(safe-area-inset-right) */
/* #endif */
}
.fui-footer__link {
......
......@@ -180,6 +180,14 @@
this.handleFade()
this.endObserver()
}
// #ifndef H5
// 当前版本 SDK 存在 Bug 会导致无法触发可视观测 observe 回调, 所以直接执行
// https://github.com/dcloudio/uni-app/issues/5201
this.handleFade()
this.endObserver()
console.debug('[Bug] uni.createIntersectionObserver: https://github.com/dcloudio/uni-app/issues/5201')
// #endif
},
handleAppear(e) {
if (this.observer || this.show) return;
......
<template>
<view class="hljs">
<rich-text :nodes="code" space="nbsp"></rich-text>
</view>
</template>
<script>
import hljs from './high-light/index.js'
// 支持的解析语言列表
const LANGUAGE_LIST = [
'javascript',
'css',
'xml',
'sql',
'typescript',
'markdown',
'c++',
'c',
];
export default {
name: "firstui-audio",
props: {
codeText: {
type: String,
default: ''
},
language: {
type: String,
default: 'javascript'
}
},
data() {
return {
code: ''
};
},
created() {
this.parseCode(this.codeText, this.language)
},
methods: {
parseCode(input, language) {
const lang = LANGUAGE_LIST.includes(language) ? language : 'javascript'
const {
value
} = hljs.highlight(lang, input)
const highlighted = value.replace('&amp;', '&').trim()
let codeResult = `<code class="${lang}">${highlighted}</code>`
codeResult = codeResult.replace(/\n/g, "<br/>").replace('\<code\>', '')
this.code = codeResult;
}
}
}
</script>
<style>
/*
Style with support for rainbow parens
*/
.hljs {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
overflow-x: auto;
padding: 0.5em;
background: #282c34;
color: #d1d9e1;
}
.hljs-comment,
.hljs-quote {
color: #969896;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-type,
.hljs-addition {
color: #cc99cc;
}
.hljs-number,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #f99157;
}
.hljs-string,
.hljs-doctag,
.hljs-regexp {
color: #8abeb7;
}
.hljs-title,
.hljs-name,
.hljs-section,
.hljs-built_in {
color: #b5bd68;
}
.hljs-variable,
.hljs-template-variable,
.hljs-selector-id,
.hljs-class .hljs-title {
color: #ffcc66;
}
.hljs-section,
.hljs-name,
.hljs-strong {
font-weight: bold;
}
.hljs-symbol,
.hljs-bullet,
.hljs-subst,
.hljs-meta,
.hljs-link {
color: #f99157;
}
.hljs-deletion {
color: #dc322f;
}
.hljs-formula {
background: #eee8d5;
}
.hljs-attr,
.hljs-attribute {
color: #81a2be;
}
.hljs-emphasis {
font-style: italic;
}
/* #ifdef VUE3 */
:deep(.hljs-comment),
:deep(.hljs-quote){
color: #969896;
font-style: italic;
}
:deep(.hljs-keyword),
:deep(.hljs-selector-tag),
:deep(.hljs-literal),
:deep(.hljs-type),
:deep(.hljs-addition) {
color: #cc99cc;
}
:deep(.hljs-number),
:deep(.hljs-selector-attr),
:deep(.hljs-selector-pseudo) {
color: #f99157;
}
:deep(.hljs-string),
:deep(.hljs-doctag),
:deep(.hljs-regexp) {
color: #8abeb7;
}
:deep(.hljs-title),
:deep(.hljs-name),
:deep(.hljs-section),
:deep(.hljs-built_in) {
color: #b5bd68;
}
:deep(.hljs-variable),
:deep(.hljs-template-variable),
:deep(.hljs-selector-id),
:deep(.hljs-class .hljs-title) {
color: #ffcc66;
}
:deep(.hljs-section),
:deep(.hljs-name),
:deep(.hljs-strong) {
font-weight: bold;
}
:deep(.hljs-symbol),
:deep(.hljs-bullet),
:deep(.hljs-subst),
:deep(.hljs-meta),
:deep(.hljs-link) {
color: #f99157;
}
:deep(.hljs-deletion) {
color: #dc322f;
}
:deep(.hljs-formula) {
background: #eee8d5;
}
:deep(.hljs-attr),
:deep(.hljs-attribute) {
color: #81a2be;
}
:deep(.hljs-emphasis) {
font-style: italic;
}
/* #endif */
</style>
......@@ -16,7 +16,8 @@
<!-- code类型 -->
<block v-else-if="item && item.tag == 'code'">
<view class="mb10" :class="item.classStr" :style="item.styleStr">
<firstui-code :codeText="item.content" :language="item.attr && item.attr.lang"></firstui-code>
<text>{{ item.content }}</text>
<!-- <firstui-code :codeText="item.content" :language="item.attr && item.attr.lang"></firstui-code> -->
</view>
</block>
......@@ -172,10 +173,8 @@
</template>
<script>
import firstuiCode from './firstui-code.vue'
import firstuiAudio from './firstui-audio.vue'
import HtmlToJson from './utils/html2json.js';
import marked from './marked/index.js'
import util from './utils/util.js';
const BIND_NAME = 'fuiParse'
export default {
......@@ -187,7 +186,6 @@
}
},
components: {
firstuiCode,
firstuiAudio
},
props: {
......@@ -207,10 +205,10 @@
if (!val) return;
// 采用markdown解析
if (this.language === 'markdown' || this.language === 'md') {
const parseNodes = marked(val);
setTimeout(() => {
this._parseNodes(parseNodes)
}, 0);
// const parseNodes = marked(val);
// setTimeout(() => {
// this._parseNodes(parseNodes)
// }, 0);
} else {
// 默认采用html解析
setTimeout(() => {
......
/**
* Modified by: firstui
* organization: FirstUI(https://www.firstui.cn/)
*/
import hljs from './highlight.code.js'
import javascript from './languages/javascript.js'
import css from './languages/css.js'
import xml from './languages/xml.js'
import sql from './languages/sql.js'
import typescript from './languages/typescript.js'
import markdown from './languages/markdown.js'
import cpp from './languages/cpp.js'
import c from './languages/c.js'
hljs.registerLanguage('javascript', javascript);
hljs.registerLanguage('css', css);
hljs.registerLanguage('xml', xml);
hljs.registerLanguage('sql', sql);
hljs.registerLanguage('typescript', typescript);
hljs.registerLanguage('markdown', markdown);
hljs.registerLanguage('c++', cpp);
hljs.registerLanguage('c', c);
export default hljs;
/*
Language: C-like foundation grammar for C/C++ grammars
Author: Ivan Sagalaev <maniac@softwaremaniacs.org>
Contributors: Evgeny Stepanischev <imbolk@gmail.com>, Zaven Muradyan <megalivoithos@gmail.com>, Roel Deckers <admin@codingcat.nl>, Sam Wu <samsam2310@gmail.com>, Jordi Petit <jordi.petit@gmail.com>, Pieter Vantorre <pietervantorre@gmail.com>, Google Inc. (David Benjamin) <davidben@google.com>
Modified by: firstui
organization: FirstUI(https://www.firstui.cn/)
*/
/* In the future the intention is to split out the C/C++ grammars distinctly
since they are separate languages. They will likely share a common foundation
though, and this file sets the groundwork for that - so that we get the breaking
change in v10 and don't have to change the requirements again later.
See: https://github.com/highlightjs/highlight.js/issues/2146
*/
import {
optional
} from '../regex.js'
/** @type LanguageFn */
export default function(hljs) {
// added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does
// not include such support nor can we be sure all the grammars depending
// on it would desire this behavior
const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', {
contains: [{
begin: /\\\n/
}]
});
const DECLTYPE_AUTO_RE = 'decltype\\(auto\\)';
const NAMESPACE_RE = '[a-zA-Z_]\\w*::';
const TEMPLATE_ARGUMENT_RE = '<[^<>]+>';
const FUNCTION_TYPE_RE = '(' +
DECLTYPE_AUTO_RE + '|' +
optional(NAMESPACE_RE) +
'[a-zA-Z_]\\w*' + optional(TEMPLATE_ARGUMENT_RE) +
')';
const CPP_PRIMITIVE_TYPES = {
className: 'keyword',
begin: '\\b[a-z\\d_]*_t\\b'
};
// https://en.cppreference.com/w/cpp/language/escape
// \\ \x \xFF \u2837 \u00323747 \374
const CHARACTER_ESCAPES = '\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)';
const STRINGS = {
className: 'string',
variants: [{
begin: '(u8?|U|L)?"',
end: '"',
illegal: '\\n',
contains: [hljs.BACKSLASH_ESCAPE]
},
{
begin: '(u8?|U|L)?\'(' + CHARACTER_ESCAPES + "|.)",
end: '\'',
illegal: '.'
},
// hljs.END_SAME_AS_BEGIN({
// begin: /(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,
// end: /\)([^()\\ ]{0,16})"/
// })
]
};
const NUMBERS = {
className: 'number',
variants: [{
begin: '\\b(0b[01\']+)'
},
{
begin: '(-?)\\b([\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)(u|U|l|L|ul|UL|f|F|b|B)'
},
{
begin: '(-?)(\\b0[xX][a-fA-F0-9\']+|(\\b[\\d\']+(\\.[\\d\']*)?|\\.[\\d\']+)([eE][-+]?[\\d\']+)?)'
}
],
relevance: 0
};
const PREPROCESSOR = {
className: 'meta',
begin: /#\s*[a-z]+\b/,
end: /$/,
keywords: {
'meta-keyword': 'if else elif endif define undef warning error line ' +
'pragma _Pragma ifdef ifndef include'
},
contains: [{
begin: /\\\n/,
relevance: 0
},
hljs.inherit(STRINGS, {
className: 'meta-string'
}),
{
className: 'meta-string',
begin: /<.*?>/,
end: /$/,
illegal: '\\n'
},
C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE
]
};
const TITLE_MODE = {
className: 'title',
begin: optional(NAMESPACE_RE) + hljs.IDENT_RE,
relevance: 0
};
const FUNCTION_TITLE = optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\s*\\(';
const CPP_KEYWORDS = {
keyword: 'int float while private char char8_t char16_t char32_t catch import module export virtual operator sizeof ' +
'dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace ' +
'unsigned long volatile static protected bool template mutable if public friend ' +
'do goto auto void enum else break extern using asm case typeid wchar_t ' +
'short reinterpret_cast|10 default double register explicit signed typename try this ' +
'switch continue inline delete alignas alignof constexpr consteval constinit decltype ' +
'concept co_await co_return co_yield requires ' +
'noexcept static_assert thread_local restrict final override ' +
'atomic_bool atomic_char atomic_schar ' +
'atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong ' +
'atomic_ullong new throw return ' +
'and and_eq bitand bitor compl not not_eq or or_eq xor xor_eq',
built_in: 'std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream ' +
'auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set ' +
'unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos ' +
'asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp ' +
'fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper ' +
'isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow ' +
'printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp ' +
'strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan ' +
'vfprintf vprintf vsprintf endl initializer_list unique_ptr _Bool complex _Complex imaginary _Imaginary',
literal: 'true false nullptr NULL'
};
const EXPRESSION_CONTAINS = [
PREPROCESSOR,
CPP_PRIMITIVE_TYPES,
C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
NUMBERS,
STRINGS
];
const EXPRESSION_CONTEXT = {
// This mode covers expression context where we can't expect a function
// definition and shouldn't highlight anything that looks like one:
// `return some()`, `else if()`, `(x*sum(1, 2))`
variants: [{
begin: /=/,
end: /;/
},
{
begin: /\(/,
end: /\)/
},
{
beginKeywords: 'new throw return else',
end: /;/
}
],
keywords: CPP_KEYWORDS,
contains: EXPRESSION_CONTAINS.concat([{
begin: /\(/,
end: /\)/,
keywords: CPP_KEYWORDS,
contains: EXPRESSION_CONTAINS.concat(['self']),
relevance: 0
}]),
relevance: 0
};
const FUNCTION_DECLARATION = {
className: 'function',
begin: '(' + FUNCTION_TYPE_RE + '[\\*&\\s]+)+' + FUNCTION_TITLE,
returnBegin: true,
end: /[{;=]/,
excludeEnd: true,
keywords: CPP_KEYWORDS,
illegal: /[^\w\s\*&:<>]/,
contains: [{ // to prevent it from being confused as the function title
begin: DECLTYPE_AUTO_RE,
keywords: CPP_KEYWORDS,
relevance: 0
},
{
begin: FUNCTION_TITLE,
returnBegin: true,
contains: [TITLE_MODE],
relevance: 0
},
{
className: 'params',
begin: /\(/,
end: /\)/,
keywords: CPP_KEYWORDS,
relevance: 0,
contains: [
C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
STRINGS,
NUMBERS,
CPP_PRIMITIVE_TYPES,
// Count matching parentheses.
{
begin: /\(/,
end: /\)/,
keywords: CPP_KEYWORDS,
relevance: 0,
contains: [
'self',
C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
STRINGS,
NUMBERS,
CPP_PRIMITIVE_TYPES
]
}
]
},
CPP_PRIMITIVE_TYPES,
C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
PREPROCESSOR
]
};
return {
aliases: [
'c',
'cc',
'h',
'c++',
'h++',
'hpp',
'hh',
'hxx',
'cxx'
],
keywords: CPP_KEYWORDS,
// the base c-like language will NEVER be auto-detected, rather the
// derivitives: c, c++, arduino turn auto-detect back on for themselves
disableAutodetect: true,
illegal: '</',
contains: [].concat(
EXPRESSION_CONTEXT,
FUNCTION_DECLARATION,
EXPRESSION_CONTAINS,
[
PREPROCESSOR,
{ // containers: ie, `vector <int> rooms (9);`
begin: '\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<',
end: '>',
keywords: CPP_KEYWORDS,
contains: [
'self',
CPP_PRIMITIVE_TYPES
]
},
{
begin: hljs.IDENT_RE + '::',
keywords: CPP_KEYWORDS
},
{
className: 'class',
beginKeywords: 'enum class struct union',
end: /[{;:<>=]/,
contains: [{
beginKeywords: "final class struct"
},
hljs.TITLE_MODE
]
}
]),
exports: {
preprocessor: PREPROCESSOR,
strings: STRINGS,
keywords: CPP_KEYWORDS
}
};
}
/*
Language: C
Category: common, system
Website: https://en.wikipedia.org/wiki/C_(programming_language)
Modified by: firstui
organization: FirstUI(https://www.firstui.cn/)
*/
import cLike from './c-like.js';
/** @type LanguageFn */
export default function(hljs) {
const lang = cLike(hljs);
// Until C is actually different than C++ there is no reason to auto-detect C
// as it's own language since it would just fail auto-detect testing or
// simply match with C++.
//
// See further comments in c-like.js.
// lang.disableAutodetect = false;
lang.name = 'C';
lang.aliases = ['c', 'h'];
return lang;
}
/*
Language: C++
Category: common, system
Website: https://isocpp.org
Modified by: firstui
organization: FirstUI(https://www.firstui.cn/)
*/
import cLike from './c-like.js';
/** @type LanguageFn */
export default function(hljs) {
const lang = cLike(hljs);
// return auto-detection back on
lang.disableAutodetect = false;
lang.name = 'C++';
lang.aliases = ['cc', 'c++', 'h++', 'hpp', 'hh', 'hxx', 'cxx'];
return lang;
}
/**
* Modified by: firstui
* organization: FirstUI(https://www.firstui.cn/)
*/
export default function(hljs) {
var FUNCTION_LIKE = {
begin: /[\w-]+\(/, returnBegin: true,
contains: [
{
className: 'built_in',
begin: /[\w-]+/
},
{
begin: /\(/, end: /\)/,
contains: [
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
hljs.CSS_NUMBER_MODE,
]
}
]
}
var ATTRIBUTE = {
className: 'attribute',
begin: /\S/, end: ':', excludeEnd: true,
starts: {
endsWithParent: true, excludeEnd: true,
contains: [
FUNCTION_LIKE,
hljs.CSS_NUMBER_MODE,
hljs.QUOTE_STRING_MODE,
hljs.APOS_STRING_MODE,
hljs.C_BLOCK_COMMENT_MODE,
{
className: 'number', begin: '#[0-9A-Fa-f]+'
},
{
className: 'meta', begin: '!important'
}
]
}
}
var AT_IDENTIFIER = '@[a-z-]+' // @font-face
var AT_MODIFIERS = "and or not only"
var MEDIA_TYPES = "all print screen speech"
var AT_PROPERTY_RE = /@\-?\w[\w]*(\-\w+)*/ // @-webkit-keyframes
var IDENT_RE = '[a-zA-Z-][a-zA-Z0-9_-]*';
var RULE = {
begin: /(?:[A-Z\_\.\-]+|--[a-zA-Z0-9_-]+)\s*:/, returnBegin: true, end: ';', endsWithParent: true,
contains: [
ATTRIBUTE
]
};
return {
case_insensitive: true,
illegal: /[=\/|'\$]/,
contains: [
hljs.C_BLOCK_COMMENT_MODE,
{
className: 'selector-id', begin: /#[A-Za-z0-9_-]+/
},
{
className: 'selector-class', begin: /\.[A-Za-z0-9_-]+/
},
{
className: 'selector-attr',
begin: /\[/, end: /\]/,
illegal: '$',
contains: [
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
]
},
{
className: 'selector-pseudo',
begin: /:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/
},
// matching these here allows us to treat them more like regular CSS
// rules so everything between the {} gets regular rule highlighting,
// which is what we want for page and font-face
{
begin: '@(page|font-face)',
lexemes: AT_IDENTIFIER,
keywords: '@page @font-face'
},
{
begin: '@', end: '[{;]', // at_rule eating first "{" is a good thing
// because it doesn’t let it to be parsed as
// a rule set but instead drops parser into
// the default mode which is how it should be.
illegal: /:/, // break on Less variables @var: ...
returnBegin: true,
contains: [
{
className: 'keyword',
begin: AT_PROPERTY_RE
},
{
begin: /\s/, endsWithParent: true, excludeEnd: true,
relevance: 0,
keywords: AT_MODIFIERS,
contains: [
{
begin: /[a-z-]+:/,
className:"attribute"
},
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
hljs.CSS_NUMBER_MODE
]
}
]
},
{
className: 'selector-tag', begin: IDENT_RE,
relevance: 0
},
{
begin: '{', end: '}',
illegal: /\S/,
contains: [
hljs.C_BLOCK_COMMENT_MODE,
RULE,
]
}
]
};
};
/**
* Modified by: firstui
* organization: FirstUI(https://www.firstui.cn/)
*/
export default function(hljs) {
var FRAGMENT = {
begin: '<>',
end: '</>'
};
var XML_TAG = {
begin: /<[A-Za-z0-9\\._:-]+/,
end: /\/[A-Za-z0-9\\._:-]+>|\/>/
};
var IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*';
var KEYWORDS = {
keyword:
'in of if for while finally var new function do return void else break catch ' +
'instanceof with throw case default try this switch continue typeof delete ' +
'let yield const export super debugger as async await static ' +
// ECMAScript 6 modules import
'import from as'
,
literal:
'true false null undefined NaN Infinity',
built_in:
'eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent ' +
'encodeURI encodeURIComponent escape unescape Object Function Boolean Error ' +
'EvalError InternalError RangeError ReferenceError StopIteration SyntaxError ' +
'TypeError URIError Number Math Date String RegExp Array Float32Array ' +
'Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array ' +
'Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require ' +
'module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect ' +
'Promise'
};
var NUMBER = {
className: 'number',
variants: [
{ begin: '\\b(0[bB][01]+)n?' },
{ begin: '\\b(0[oO][0-7]+)n?' },
{ begin: hljs.C_NUMBER_RE + 'n?' }
],
relevance: 0
};
var SUBST = {
className: 'subst',
begin: '\\$\\{', end: '\\}',
keywords: KEYWORDS,
contains: [] // defined later
};
var HTML_TEMPLATE = {
begin: 'html`', end: '',
starts: {
end: '`', returnEnd: false,
contains: [
hljs.BACKSLASH_ESCAPE,
SUBST
],
subLanguage: 'xml',
}
};
var CSS_TEMPLATE = {
begin: 'css`', end: '',
starts: {
end: '`', returnEnd: false,
contains: [
hljs.BACKSLASH_ESCAPE,
SUBST
],
subLanguage: 'css',
}
};
var TEMPLATE_STRING = {
className: 'string',
begin: '`', end: '`',
contains: [
hljs.BACKSLASH_ESCAPE,
SUBST
]
};
SUBST.contains = [
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
HTML_TEMPLATE,
CSS_TEMPLATE,
TEMPLATE_STRING,
NUMBER,
hljs.REGEXP_MODE
];
var PARAMS_CONTAINS = SUBST.contains.concat([
hljs.C_BLOCK_COMMENT_MODE,
hljs.C_LINE_COMMENT_MODE
]);
return {
aliases: ['js', 'jsx', 'mjs', 'cjs'],
keywords: KEYWORDS,
contains: [
{
className: 'meta',
relevance: 10,
begin: /^\s*['"]use (strict|asm)['"]/
},
{
className: 'meta',
begin: /^#!/, end: /$/
},
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
HTML_TEMPLATE,
CSS_TEMPLATE,
TEMPLATE_STRING,
hljs.C_LINE_COMMENT_MODE,
hljs.COMMENT(
'/\\*\\*',
'\\*/',
{
relevance : 0,
contains : [
{
className : 'doctag',
begin : '@[A-Za-z]+',
contains : [
{
className: 'type',
begin: '\\{',
end: '\\}',
relevance: 0
},
{
className: 'variable',
begin: IDENT_RE + '(?=\\s*(-)|$)',
endsParent: true,
relevance: 0
},
// eat spaces (not newlines) so we can find
// types or variables
{
begin: /(?=[^\n])\s/,
relevance: 0
},
]
}
]
}
),
hljs.C_BLOCK_COMMENT_MODE,
NUMBER,
{ // object attr container
begin: /[{,\n]\s*/, relevance: 0,
contains: [
{
begin: IDENT_RE + '\\s*:', returnBegin: true,
relevance: 0,
contains: [{className: 'attr', begin: IDENT_RE, relevance: 0}]
}
]
},
{ // "value" container
begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*',
keywords: 'return throw case',
contains: [
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
hljs.REGEXP_MODE,
{
className: 'function',
begin: '(\\(.*?\\)|' + IDENT_RE + ')\\s*=>', returnBegin: true,
end: '\\s*=>',
contains: [
{
className: 'params',
variants: [
{
begin: IDENT_RE
},
{
begin: /\(\s*\)/,
},
{
begin: /\(/, end: /\)/,
excludeBegin: true, excludeEnd: true,
keywords: KEYWORDS,
contains: PARAMS_CONTAINS
}
]
}
]
},
{
className: '',
begin: /\s/,
end: /\s*/,
skip: true,
},
{ // JSX
variants: [
{ begin: FRAGMENT.begin, end: FRAGMENT.end },
{ begin: XML_TAG.begin, end: XML_TAG.end }
],
subLanguage: 'xml',
contains: [
{
begin: XML_TAG.begin, end: XML_TAG.end, skip: true,
contains: ['self']
}
]
},
],
relevance: 0
},
{
className: 'function',
beginKeywords: 'function', end: /\{/, excludeEnd: true,
contains: [
hljs.inherit(hljs.TITLE_MODE, {begin: IDENT_RE}),
{
className: 'params',
begin: /\(/, end: /\)/,
excludeBegin: true,
excludeEnd: true,
contains: PARAMS_CONTAINS
}
],
illegal: /\[|%/
},
{
begin: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something`
},
hljs.METHOD_GUARD,
{ // ES6 class
className: 'class',
beginKeywords: 'class', end: /[{;=]/, excludeEnd: true,
illegal: /[:"\[\]]/,
contains: [
{beginKeywords: 'extends'},
hljs.UNDERSCORE_TITLE_MODE
]
},
{
beginKeywords: 'constructor get set', end: /\{/, excludeEnd: true
}
],
illegal: /#(?!!)/
};
};
/**
* Modified by: firstui
* organization: FirstUI(https://www.firstui.cn/)
*/
export default function(hljs) {
return {
aliases: ['md', 'mkdown', 'mkd'],
contains: [
// highlight headers
{
className: 'section',
variants: [
{ begin: '^#{1,6}', end: '$' },
{ begin: '^.+?\\n[=-]{2,}$' }
]
},
// inline html
{
begin: '<', end: '>',
subLanguage: 'xml',
relevance: 0
},
// lists (indicators only)
{
className: 'bullet',
begin: '^\\s*([*+-]|(\\d+\\.))\\s+'
},
// strong segments
{
className: 'strong',
begin: '[*_]{2}.+?[*_]{2}'
},
// emphasis segments
{
className: 'emphasis',
variants: [
{ begin: '\\*.+?\\*' },
{ begin: '_.+?_'
, relevance: 0
}
]
},
// blockquotes
{
className: 'quote',
begin: '^>\\s+', end: '$'
},
// code snippets
{
className: 'code',
variants: [
{
begin: '^```\\w*\\s*$', end: '^```[ ]*$'
},
{
begin: '`.+?`'
},
{
begin: '^( {4}|\\t)', end: '$',
relevance: 0
}
]
},
// horizontal rules
{
begin: '^[-\\*]{3,}', end: '$'
},
// using links - title and link
{
begin: '\\[.+?\\][\\(\\[].*?[\\)\\]]',
returnBegin: true,
contains: [
{
className: 'string',
begin: '\\[', end: '\\]',
excludeBegin: true,
returnEnd: true,
relevance: 0
},
{
className: 'link',
begin: '\\]\\(', end: '\\)',
excludeBegin: true, excludeEnd: true
},
{
className: 'symbol',
begin: '\\]\\[', end: '\\]',
excludeBegin: true, excludeEnd: true
}
],
relevance: 10
},
{
begin: /^\[[^\n]+\]:/,
returnBegin: true,
contains: [
{
className: 'symbol',
begin: /\[/, end: /\]/,
excludeBegin: true, excludeEnd: true
},
{
className: 'link',
begin: /:\s*/, end: /$/,
excludeBegin: true
}
]
}
]
};
};
/**
* Modified by: firstui
* organization: FirstUI(https://www.firstui.cn/)
*/
export default function(hljs) {
var JS_IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*';
var KEYWORDS = {
keyword:
'in if for while finally var new function do return void else break catch ' +
'instanceof with throw case default try this switch continue typeof delete ' +
'let yield const class public private protected get set super ' +
'static implements enum export import declare type namespace abstract ' +
'as from extends async await',
literal:
'true false null undefined NaN Infinity',
built_in:
'eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent ' +
'encodeURI encodeURIComponent escape unescape Object Function Boolean Error ' +
'EvalError InternalError RangeError ReferenceError StopIteration SyntaxError ' +
'TypeError URIError Number Math Date String RegExp Array Float32Array ' +
'Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array ' +
'Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require ' +
'module console window document any number boolean string void Promise'
};
var DECORATOR = {
className: 'meta',
begin: '@' + JS_IDENT_RE,
};
var ARGS =
{
begin: '\\(',
end: /\)/,
keywords: KEYWORDS,
contains: [
'self',
hljs.QUOTE_STRING_MODE,
hljs.APOS_STRING_MODE,
hljs.NUMBER_MODE
]
};
var PARAMS = {
className: 'params',
begin: /\(/, end: /\)/,
excludeBegin: true,
excludeEnd: true,
keywords: KEYWORDS,
contains: [
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
DECORATOR,
ARGS
]
};
var NUMBER = {
className: 'number',
variants: [
{ begin: '\\b(0[bB][01]+)n?' },
{ begin: '\\b(0[oO][0-7]+)n?' },
{ begin: hljs.C_NUMBER_RE + 'n?' }
],
relevance: 0
};
var SUBST = {
className: 'subst',
begin: '\\$\\{', end: '\\}',
keywords: KEYWORDS,
contains: [] // defined later
};
var HTML_TEMPLATE = {
begin: 'html`', end: '',
starts: {
end: '`', returnEnd: false,
contains: [
hljs.BACKSLASH_ESCAPE,
SUBST
],
subLanguage: 'xml',
}
};
var CSS_TEMPLATE = {
begin: 'css`', end: '',
starts: {
end: '`', returnEnd: false,
contains: [
hljs.BACKSLASH_ESCAPE,
SUBST
],
subLanguage: 'css',
}
};
var TEMPLATE_STRING = {
className: 'string',
begin: '`', end: '`',
contains: [
hljs.BACKSLASH_ESCAPE,
SUBST
]
};
SUBST.contains = [
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
HTML_TEMPLATE,
CSS_TEMPLATE,
TEMPLATE_STRING,
NUMBER,
hljs.REGEXP_MODE
];
return {
aliases: ['ts'],
keywords: KEYWORDS,
contains: [
{
className: 'meta',
begin: /^\s*['"]use strict['"]/
},
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
HTML_TEMPLATE,
CSS_TEMPLATE,
TEMPLATE_STRING,
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
NUMBER,
{ // "value" container
begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*',
keywords: 'return throw case',
contains: [
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
hljs.REGEXP_MODE,
{
className: 'function',
begin: '(\\(.*?\\)|' + hljs.IDENT_RE + ')\\s*=>', returnBegin: true,
end: '\\s*=>',
contains: [
{
className: 'params',
variants: [
{
begin: hljs.IDENT_RE
},
{
begin: /\(\s*\)/,
},
{
begin: /\(/, end: /\)/,
excludeBegin: true, excludeEnd: true,
keywords: KEYWORDS,
contains: [
'self',
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE
]
}
]
}
]
}
],
relevance: 0
},
{
className: 'function',
beginKeywords: 'function', end: /[\{;]/, excludeEnd: true,
keywords: KEYWORDS,
contains: [
'self',
hljs.inherit(hljs.TITLE_MODE, { begin: JS_IDENT_RE }),
PARAMS
],
illegal: /%/,
relevance: 0 // () => {} is more typical in TypeScript
},
{
beginKeywords: 'constructor', end: /[\{;]/, excludeEnd: true,
contains: [
'self',
PARAMS
]
},
{ // prevent references like module.id from being higlighted as module definitions
begin: /module\./,
keywords: { built_in: 'module' },
relevance: 0
},
{
beginKeywords: 'module', end: /\{/, excludeEnd: true
},
{
beginKeywords: 'interface', end: /\{/, excludeEnd: true,
keywords: 'interface extends'
},
{
begin: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something`
},
{
begin: '\\.' + hljs.IDENT_RE, relevance: 0 // hack: prevents detection of keywords after dots
},
DECORATOR,
ARGS
]
};
};
/**
* Modified by: firstui
* organization: FirstUI(https://www.firstui.cn/)
*/
export default function(hljs) {
var XML_IDENT_RE = '[A-Za-z0-9\\._:-]+';
var XML_ENTITIES = {
className: 'symbol',
begin: '&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;'
};
var XML_META_KEYWORDS = {
begin: '\\s',
contains:[
{
className: 'meta-keyword',
begin: '#?[a-z_][a-z1-9_-]+',
illegal: '\\n',
}
]
};
var XML_META_PAR_KEYWORDS = hljs.inherit(XML_META_KEYWORDS, {begin: '\\(', end: '\\)'});
var APOS_META_STRING_MODE = hljs.inherit(hljs.APOS_STRING_MODE, {className: 'meta-string'});
var QUOTE_META_STRING_MODE = hljs.inherit(hljs.QUOTE_STRING_MODE, {className: 'meta-string'});
var TAG_INTERNALS = {
endsWithParent: true,
illegal: /</,
relevance: 0,
contains: [
{
className: 'attr',
begin: XML_IDENT_RE,
relevance: 0
},
{
begin: /=\s*/,
relevance: 0,
contains: [
{
className: 'string',
endsParent: true,
variants: [
{begin: /"/, end: /"/, contains: [XML_ENTITIES]},
{begin: /'/, end: /'/, contains: [XML_ENTITIES]},
{begin: /[^\s"'=<>`]+/}
]
}
]
}
]
};
return {
aliases: ['html', 'xhtml', 'rss', 'atom', 'xjb', 'xsd', 'xsl', 'plist', 'wsf', 'svg'],
case_insensitive: true,
contains: [
{
className: 'meta',
begin: '<![a-z]', end: '>',
relevance: 10,
contains: [
XML_META_KEYWORDS,
QUOTE_META_STRING_MODE,
APOS_META_STRING_MODE,
XML_META_PAR_KEYWORDS,
{
begin: '\\[', end: '\\]',
contains:[
{
className: 'meta',
begin: '<![a-z]', end: '>',
contains: [
XML_META_KEYWORDS,
XML_META_PAR_KEYWORDS,
QUOTE_META_STRING_MODE,
APOS_META_STRING_MODE
]
}
]
}
]
},
hljs.COMMENT(
'<!--',
'-->',
{
relevance: 10
}
),
{
begin: '<\\!\\[CDATA\\[', end: '\\]\\]>',
relevance: 10
},
XML_ENTITIES,
{
className: 'meta',
begin: /<\?xml/, end: /\?>/, relevance: 10
},
{
begin: /<\?(php)?/, end: /\?>/,
subLanguage: 'php',
contains: [
// We don't want the php closing tag ?> to close the PHP block when
// inside any of the following blocks:
{begin: '/\\*', end: '\\*/', skip: true},
{begin: 'b"', end: '"', skip: true},
{begin: 'b\'', end: '\'', skip: true},
hljs.inherit(hljs.APOS_STRING_MODE, {illegal: null, className: null, contains: null, skip: true}),
hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null, className: null, contains: null, skip: true})
]
},
{
className: 'tag',
/*
The lookahead pattern (?=...) ensures that 'begin' only matches
'<style' as a single word, followed by a whitespace or an
ending braket. The '$' is needed for the lexeme to be recognized
by hljs.subMode() that tests lexemes outside the stream.
*/
begin: '<style(?=\\s|>)', end: '>',
keywords: {name: 'style'},
contains: [TAG_INTERNALS],
starts: {
end: '</style>', returnEnd: true,
subLanguage: ['css', 'xml']
}
},
{
className: 'tag',
// See the comment in the <style tag about the lookahead pattern
begin: '<script(?=\\s|>)', end: '>',
keywords: {name: 'script'},
contains: [TAG_INTERNALS],
starts: {
end: '\<\/script\>', returnEnd: true,
subLanguage: ['actionscript', 'javascript', 'handlebars', 'xml']
}
},
{
className: 'tag',
begin: '</?', end: '/?>',
contains: [
{
className: 'name', begin: /[^\/><\s]+/, relevance: 0
},
TAG_INTERNALS
]
}
]
};
};
/**
* @param {string} value
* @returns {RegExp}
* */
export function escape(value) {
return new RegExp(value.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'), 'm');
}
/**
* @param {RegExp | string } re
* @returns {string}
*/
export function source(re) {
if (!re) return null;
if (typeof re === "string") return re;
return re.source;
}
/**
* @param {RegExp | string } re
* @returns {string}
*/
export function lookahead(re) {
return concat('(?=', re, ')');
}
/**
* @param {RegExp | string } re
* @returns {string}
*/
export function anyNumberOfTimes(re) {
return concat('(', re, ')*');
}
/**
* @param {RegExp | string } re
* @returns {string}
*/
export function optional(re) {
return concat('(', re, ')?');
}
/**
* @param {...(RegExp | string) } args
* @returns {string}
*/
export function concat(...args) {
const joined = args.map((x) => source(x)).join("");
return joined;
}
/**
* Any of the passed expresssions may match
*
* Creates a huge this | this | that | that match
* @param {(RegExp | string)[] } args
* @returns {string}
*/
export function either(...args) {
const joined = '(' + args.map((x) => source(x)).join("|") + ")";
return joined;
}
/**
* @param {RegExp} re
* @returns {number}
*/
export function countMatchGroups(re) {
return (new RegExp(re.toString() + '|')).exec('').length - 1;
}
/**
* Does lexeme start with a regular expression match at the beginning
* @param {RegExp} re
* @param {string} lexeme
*/
export function startsWith(re, lexeme) {
const match = re && re.exec(lexeme);
return match && match.index === 0;
}
// join logically computes regexps.join(separator), but fixes the
// backreferences so they continue to match.
// it also places each individual regular expression into it's own
// match group, keeping track of the sequencing of those match groups
// is currently an exercise for the caller. :-)
/**
* @param {(string | RegExp)[]} regexps
* @param {string} separator
* @returns {string}
*/
export function join(regexps, separator = "|") {
// backreferenceRe matches an open parenthesis or backreference. To avoid
// an incorrect parse, it additionally matches the following:
// - [...] elements, where the meaning of parentheses and escapes change
// - other escape sequences, so we do not misparse escape sequences as
// interesting elements
// - non-matching or lookahead parentheses, which do not capture. These
// follow the '(' with a '?'.
const backreferenceRe = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;
let numCaptures = 0;
let ret = '';
for (let i = 0; i < regexps.length; i++) {
numCaptures += 1;
const offset = numCaptures;
let re = source(regexps[i]);
if (i > 0) {
ret += separator;
}
ret += "(";
while (re.length > 0) {
const match = backreferenceRe.exec(re);
if (match == null) {
ret += re;
break;
}
ret += re.substring(0, match.index);
re = re.substring(match.index + match[0].length);
if (match[0][0] === '\\' && match[1]) {
// Adjust the backreference.
ret += '\\' + String(Number(match[1]) + offset);
} else {
ret += match[0];
if (match[0] === '(') {
numCaptures++;
}
}
}
ret += ")";
}
return ret;
}
......@@ -13,18 +13,14 @@
{
"path": "pages/common/about/index",
"style": {
"navigationBarTitleText": "关于我们",
"backgroundColorTop": "#FFFFFF",
"backgroundColorBottom": "#FFFFFF"
"navigationBarTitleText": "关于我们"
}
},
// === 问题反馈 ===
{
"path": "pages/common/feedback/index",
"style": {
"navigationBarTitleText": "问题反馈",
"backgroundColorTop": "#FFFFFF",
"backgroundColorBottom": "#FFFFFF"
"navigationBarTitleText": "问题反馈"
}
},
// === Webview ===
......@@ -48,9 +44,7 @@
// #ifdef H5
"titleNView": false,
// #endif
"navigationBarTitleText": "开发中",
"backgroundColorTop": "#FFFFFF",
"backgroundColorBottom": "#FFFFFF"
"navigationBarTitleText": "开发中"
}
},
// === 版本更新 ===
......@@ -75,7 +69,7 @@
"path": "pages/common/notice/index",
"style": {
"navigationStyle": "custom",
"background": "transparent",
"backgroundColor": "transparent",
"app-plus": {
"animationDuration": 200,
"animationType": "fade-in",
......@@ -105,6 +99,8 @@
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8",
"backgroundColorTop": "#F8F8F8",
"backgroundColorBottom": "#F8F8F8",
"pageOrientation": "portrait",
"app-plus": {
"scrollIndicator": "none",
......
......@@ -96,7 +96,7 @@
<view class="h-auto p-1">
<scroll-view scroll-y :style="{ height: `${height}px` }">
<FuiParseGroup class="notice-content" @preview="preview" @atap="atap">
<FuiParse :nodes="notice.content" language="md" />
<FuiParse :nodes="notice.content" />
</FuiParseGroup>
</scroll-view>
</view>
......@@ -125,6 +125,8 @@
}
.notice-mask {
width: 100%;
height: 100%;
position: fixed;
inset: 0;
/* #ifndef APP-NVUE */
......
......@@ -38,12 +38,13 @@
<template>
<view class="wrap">
<template v-if="images.length > 0">
<fui-lazyload
<CacheImage
class="image"
v-for="(item, index) in images"
:key="item.src"
:src="item.src"
width="750"
height="0"
:radius="0"
@tap="preview(index)"
/>
......
<script lang="ts" setup>
import URI from 'urijs'
import * as _ from 'lodash-es'
import { isProdMode } from '@/utils/env'
const page = reactive({
security: false,
......@@ -37,9 +39,18 @@
}
// #ifdef APP-PLUS
// 白名单同源检测
if (isSameOrigin(new URI(page.link))) {
// 本地网页或白名单同源检测
if (page.link.startsWith('/hybrid/') || page.link.startsWith('/static/') || isSameOrigin(new URI(page.link))) {
page.security = true
// 延迟获取 webview 对象,插入 js 文件
setTimeout(() => {
const pages = getCurrentPages()
const currentPage = pages[pages.length - 1]
const currentWebview = currentPage.$getAppWebview()
const webview = currentWebview.children()[0]
webview.appendJsFile('_www/static/uni.webview.1.5.6.js')
}, 1000)
} else {
// 对于不安全或不信任的网站地址或可能触发 plus API 的来源,采用手动创建 webview 的方式打开
const { windowHeight, statusBarHeight } = uni.getSystemInfoSync()
......@@ -62,7 +73,7 @@
})
// 安全域白名单,防止 APP 环境的意外注入和非法安全调用 plus API 的问题
const allows = ['yiring.com']
const allows = ['yiring.com', 'uniapp.dcloud.io']
// 在安全域白名单中,但仍然需要排除的链接(通常是代理的网站链接)
const denyLinks = []
function isSameOrigin(url: URI) {
......@@ -75,12 +86,26 @@
return regex.test(url.hostname())
})
}
// 监听来自 webview 的消息
const onPostMessage = _.debounce(function (e: { detail: { data: any } }) {
console.warn('onPostMessage', e)
if (!isProdMode()) {
Message.alert(JSON.stringify(e.detail.data))
}
}, 200)
</script>
<template>
<view class="wrap" v-if="page.link">
<template v-if="page.security">
<web-view :src="page.link" :update-title="!page.title" :webview-styles="page.styles" />
<web-view
:src="page.link"
:update-title="!page.title"
:webview-styles="page.styles"
@message="onPostMessage"
/>
</template>
</view>
</template>
......@@ -12,7 +12,6 @@ declare module 'vue' {
FDragItem: typeof import('./../src/components/FirstUI/fui-drag/f-drag-item.vue')['default']
FIndexListItem: typeof import('./../src/components/FirstUI/fui-index-list/f-index-list-item.vue')['default']
FirstuiAudio: typeof import('./../src/components/FirstUI/fui-parse/firstui-audio.vue')['default']
FirstuiCode: typeof import('./../src/components/FirstUI/fui-parse/firstui-code.vue')['default']
FuiActionsheet: typeof import('./../src/components/FirstUI/fui-actionsheet/fui-actionsheet.vue')['default']
FuiAlert: typeof import('./../src/components/FirstUI/fui-alert/fui-alert.vue')['default']
FuiAnimation: typeof import('./../src/components/FirstUI/fui-animation/fui-animation.vue')['default']
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论