diff --git a/components/mip-env/README.md b/components/mip-env/README.md index b74c2f67..4b36f8c9 100644 --- a/components/mip-env/README.md +++ b/components/mip-env/README.md @@ -12,11 +12,26 @@ 开发者可以将仅希望在指定的"缓存环境" 、 "平台" 、 "UA" 、 "OS"下展示的内容使用`mip-env`包裹来实现。 +1、scope中所有value都支持多值,以逗号分隔 +eg: scope={"ua":"uc,chrome","os":"!android,!ios"} + +2、scope中所有value都支持"!"语法 +eg: scope={"dp":"!baidu"} 表示在非百度平台下会展示出指定内容 + +3、多个“!”值的关系是且(&&),多个没有叹号值的关系是或(||) +eg: +scope={"ua":"!uc,!qq"} => 当不是UC浏览器和qq浏览器时会展示出指定内容 +scope={"ua":"uc,qq"} => 当是UC浏览器或qq浏览器时会展示出指定内容 + +4、当value中"!"与没有叹号同时存在时,以没叹号值为准 +eg: +scope={"ua":"uc,qq,!baidu,!qq,!chrome"} 最终会被认为是 scope={"ua":"uc,qq"} + ## 示例 ```html
- +
只在符合scope设定的环境中才会展示此内容
@@ -36,24 +51,32 @@ param: 说明: 缓存环境 必选: 否 取值: 'baidu' , 'sm' // 百度缓存 , 神马搜索缓存 - 备注: 所有值不区分大小写。填写了cache键则必须有值才行 + 备注: + 1、所有值不区分大小写。填写了cache键则必须有值才行 + 2、所有取值均可在前面加"!",表示非xx dp 说明: 分发平台(Distribution platform) 必选: 否 取值: 'baidu' , 'sm' // 百度平台 , 神马搜索平台 - 备注: 所有值不区分大小写。填写了dp键则必须有值才行 + 备注: + 1、所有值不区分大小写。填写了dp键则必须有值才行 + 2、所有取值均可在前面加"!",表示非xx ua 说明: userAgent 必选: 否 取值: 'baidu' , 'uc' , 'chrome' , 'safari' , 'firefox' , 'qq' - 备注: 所有值不区分大小写。填写了ua键则必须有值才行 + 备注: + 1、所有值不区分大小写。填写了ua键则必须有值才行 + 2、所有取值均可在前面加"!",表示非xx os 说明: 系统 必选: 否 取值: 'ios' , 'android' - 备注: 所有值不区分大小写。填写了os键则必须有值才行 + 备注: + 1、所有值不区分大小写。填写了os键则必须有值才行 + 2、所有取值均可在前面加"!",表示非xx diff --git a/components/mip-env/example/mip-env.html b/components/mip-env/example/mip-env.html index 03ae0b4b..c336975e 100644 --- a/components/mip-env/example/mip-env.html +++ b/components/mip-env/example/mip-env.html @@ -27,7 +27,7 @@
code:
- <mip-env scope={"cache":"baidu","dp":"baidu","ua":"uc","os":"ios"} > + <mip-env scope={"cache":"baidu","dp":"baidu,sm","ua":"uc,qq","os":"!ios"} >
<div>success</div>
@@ -36,7 +36,7 @@
result:
- +
success
@@ -45,7 +45,7 @@
code
- <mip-env scope={"os":"ios"} > + <mip-env scope={"os":"ios,android"} >
<div>success</div>
@@ -54,7 +54,25 @@
result:
- + +
success
+
+
+
+ +
+ code +
+ <mip-env scope={"ua":"!uc"} > +
+ <div>success</div> +
+ </mip-env> +
+
+ result: +
+
success
diff --git a/components/mip-env/mip-env.js b/components/mip-env/mip-env.js index d4ff3b8b..f346236b 100644 --- a/components/mip-env/mip-env.js +++ b/components/mip-env/mip-env.js @@ -10,8 +10,8 @@ let { } = MIP let { platform } = util -// 所支持的cache -const ALLOW_CACHE = { +// 所支持的cache和分发平台 +const ALLOW_DP_OR_CACHE = { sm: [ // 神马搜索平台(sm.cn) '.sm-tc.cn', '.transcode.cn' @@ -22,52 +22,95 @@ const ALLOW_CACHE = { ] } -// 支持的分发平台 -const ALLOW_DP = { - sm: [ - '.sm-tc.cn', - '.transcode.cn' - ], - baidu: [ - '.bdstatic.com', - '.mipcdn.com' - ] +/** + * @function splitScopeValue 取出指定scope value中带有"!"和不带有"!"的值 + * @param {string} scopeValue 指定scope value + * @returns {Array} 0键存放非"!"值 1键存放"!"值 eg: ['baidu,uc', '!qq,!chrome'] + */ +function splitScopeValue (scopeValue) { + const delDupArr = new Set(scopeValue.split(',')) + const sourceCacheArr = Array.from(delDupArr) + let resultArr = [] + if (sourceCacheArr.length === 0) { + return resultArr + } + + // 不带"!"的value集合 + resultArr[0] = sourceCacheArr.filter(item => { + return item[0] !== '!' + }) + + resultArr[1] = sourceCacheArr.filter(item => { + return item[0] === '!' + }) + + return resultArr } /** * @function cacheOk 检测缓存类型是否合规 - * @param {string} cache 缓存类型,sm or baidu + * @param {Array} sourceCacheArr 缓存类型,sm or baidu * @returns {boolean} true/false */ -function cacheOk (cache) { - const allowCacheArr = ALLOW_CACHE[cache] || [] - return allowCacheArr.some(item => { - return location.hostname.lastIndexOf(item) !== -1 +function cacheOk (sourceCacheArr) { + // 有不带"!"的cache, 则以不带"!"的cache作为最终判断依据, 判断符为“||” + // sourceCacheArr[0]为不带"!"的cache结合 + if (sourceCacheArr[0] && sourceCacheArr[0].length > 0) { + return sourceCacheArr[0].some(item => { + const allowCacheArr = ALLOW_DP_OR_CACHE[item] || [] + return allowCacheArr.some(allowCacheItem => { + return location.hostname.lastIndexOf(allowCacheItem) !== -1 + }) + }) + } + + // 带有"!"的cache合集,判断符为“&&” + // sourceCacheArr[1]为带"!"的cache合集 + return sourceCacheArr[1].every(item => { + const allowCacheArr = ALLOW_DP_OR_CACHE[item.substr(1)] || [] + return allowCacheArr.every(allowCacheItem => { + return location.hostname.lastIndexOf(allowCacheItem) === -1 + }) }) } /** - * @function dpOk 检测分发平台(dp)是否合规 - * @param {string} dp 平台类型,sm/baidu + * @function cacheOk 检测分发平台是否合规 + * @param {Array} sourceDpArr 分发平台,sm or baidu * @returns {boolean} true/false */ -function dpOk (dp) { - const allowDpArr = ALLOW_DP[dp] || [] +function dpOk (sourceDpArr) { if (!viewer.isIframed) { console.warn('require in iframe') return false } - return allowDpArr.some(item => { - return location.hostname.lastIndexOf(item) !== -1 + // 有不带"!"的cache, 则以不带"!"的dp作为最终判断依据, 判断符为“||” + // sourceDpArr[0]为不带"!"的cache结合 + if (sourceDpArr[0] && sourceDpArr[0].length > 0) { + return sourceDpArr[0].some(item => { + const allowDpArr = ALLOW_DP_OR_CACHE[item] || [] + return allowDpArr.some(allowDpItem => { + return location.hostname.lastIndexOf(allowDpItem) !== -1 + }) + }) + } + + // 带有"!"的cache合集,判断符为“&&” + // sourceDpArr[1]为带"!"的dp合集 + return sourceDpArr[1].every(item => { + const allowDpArr = ALLOW_DP_OR_CACHE[item.substr(1)] || [] + return allowDpArr.every(allowDpItem => { + return location.hostname.lastIndexOf(allowDpItem) === -1 + }) }) } /** * @function uaOk 检测userAgent是否合规 - * @param {string} ua userAgent, baidu/uc/chrome/safari/qq/firefox + * @param {Array} sourceUaArr userAgent, baidu/uc/chrome/safari/qq/firefox * @returns {boolean} true/false */ -function uaOk (ua) { +function uaOk (sourceUaArr) { const checkUaFuns = { baidu: platform.isBaidu, uc: platform.isUc, @@ -76,26 +119,44 @@ function uaOk (ua) { qq: platform.isQQ, firefox: platform.isFireFox } - if (checkUaFuns[ua] && checkUaFuns[ua]()) { - return true + // 有不带"!"的ua, 则以不带"!"ua作为最终判断依据, 判断符为“||” + // sourceUaArr[0]为带"!"的ua合集 + if (sourceUaArr && sourceUaArr[0].length > 0) { + return sourceUaArr[0].some(item => { + return (checkUaFuns[item] && checkUaFuns[item]()) + }) } - return false + + // 带有"!"的ua合集,判断符为“&&” + // sourceUaArr[1]为带"!"的ua合集 + return sourceUaArr[1].every(item => { + return (!checkUaFuns[item.substr(1)] || !checkUaFuns[item.substr(1)]()) + }) } /** * @function osOk 检测系统是否合规 - * @param {string} os 系统类型, android/ios + * @param {Array} sourceOsArr 系统类型, android/ios * @returns {boolean} true/false */ -function osOk (os) { +function osOk (sourceOsArr) { const checkOsFuns = { ios: platform.isIOS, android: platform.isAndroid } - if (checkOsFuns[os] && checkOsFuns[os]()) { - return true + // 有不带"!"的os, 则以不带"!"os作为最终判断依据, 判断符为“||” + // sourceOsArr[0]为带"!"的os合集 + if (sourceOsArr && sourceOsArr[0].length > 0) { + return sourceOsArr[0].some(item => { + return (checkOsFuns[item] && checkOsFuns[item]()) + }) } - return false + + // 带有"!"的os合集,判断符为“&&” + // sourceOsArr[1]为带"!"的os合集 + return sourceOsArr[1].every(item => { + return (!checkOsFuns[item.substr(1)] || !checkOsFuns[item.substr(1)]()) + }) } /** @@ -125,7 +186,9 @@ function scopeOk (scope) { for (const key of keys) { const param = (scopeJson[key]).toString().toLowerCase() - if (!checkFuns[key] || !checkFuns[key](param)) { + // 将value值拆分为带有!与不带有!组 + const value = splitScopeValue(param) + if (!checkFuns[key] || !checkFuns[key](value)) { console.warn(key + ' error') return false }