├── .babelrc
├── .eslintignore
├── .eslintrc.js
├── .github
└── workflows
│ └── npm-publish.yml
├── .gitignore
├── LICENSE
├── README.md
├── demo
├── index.html
├── javascript
│ └── initSdk.js
├── next.html
├── sdk
│ ├── AnalysysAgent_Encrypt.amd.min.js
│ ├── AnalysysAgent_Encrypt.min.js
│ ├── AnalysysAgent_ExposurePoint.amd.min.js
│ ├── AnalysysAgent_ExposurePoint.min.js
│ ├── AnalysysAgent_GBK.amd.min.js
│ ├── AnalysysAgent_GBK.min.js
│ ├── AnalysysAgent_JS_SDK.amd.min.js
│ ├── AnalysysAgent_JS_SDK.min.js
│ ├── AnalysysAgent_JS_SDK_HEATMAP.min.js
│ ├── AnalysysAgent_JS_SDK_VISUAL.min.js
│ ├── AnalysysAgent_MPAAS.amd.min.js
│ ├── AnalysysAgent_MPAAS.min.js
│ ├── AnalysysAgent_PageViewStayTime.amd.min.js
│ └── AnalysysAgent_PageViewStayTime.min.js
└── style
│ ├── console.js
│ ├── index.js
│ └── plugIn
│ ├── JSON.js
│ └── bootstrap
│ ├── css
│ ├── bootstrap-theme.css
│ ├── bootstrap-theme.css.map
│ ├── bootstrap-theme.min.css
│ ├── bootstrap.css
│ ├── bootstrap.css.map
│ └── bootstrap.min.css
│ ├── fonts
│ ├── glyphicons-halflings-regular.eot
│ ├── glyphicons-halflings-regular.svg
│ ├── glyphicons-halflings-regular.ttf
│ ├── glyphicons-halflings-regular.woff
│ └── glyphicons-halflings-regular.woff2
│ └── js
│ ├── bootstrap.js
│ ├── bootstrap.min.js
│ ├── jquery.min.js
│ └── npm.js
├── package.json
├── rollup.config.js
├── rollup.module.config.js
├── rollup.plugins.config.js
├── sdk
├── AnalysysAgent_Encrypt.amd.min.js
├── AnalysysAgent_Encrypt.es6.min.js
├── AnalysysAgent_Encrypt.min.js
├── AnalysysAgent_ExposurePoint.amd.min.js
├── AnalysysAgent_ExposurePoint.es6.min.js
├── AnalysysAgent_ExposurePoint.min.js
├── AnalysysAgent_GBK.amd.min.js
├── AnalysysAgent_GBK.es6.min.js
├── AnalysysAgent_GBK.min.js
├── AnalysysAgent_JS_SDK.amd.min.js
├── AnalysysAgent_JS_SDK.es6.min.js
├── AnalysysAgent_JS_SDK.min.js
├── AnalysysAgent_JS_SDK_HEATMAP.min.js
├── AnalysysAgent_JS_SDK_VISUAL.min.js
├── AnalysysAgent_MPAAS.amd.min.js
├── AnalysysAgent_MPAAS.es6.min.js
├── AnalysysAgent_MPAAS.min.js
├── AnalysysAgent_PageViewStayTime.amd.min.js
├── AnalysysAgent_PageViewStayTime.es6.min.js
├── AnalysysAgent_PageViewStayTime.min.js
└── md5.txt
├── src
├── API
│ ├── index.js
│ └── template
│ │ ├── alias.js
│ │ ├── clearSuperProperties.js
│ │ ├── freeApi.js
│ │ ├── getDistinctId.js
│ │ ├── getPresetProperties.js
│ │ ├── getSuperProperties.js
│ │ ├── getSuperProperty.js
│ │ ├── identify.js
│ │ ├── pageView.js
│ │ ├── profileAppend.js
│ │ ├── profileDelete.js
│ │ ├── profileIncrement.js
│ │ ├── profileSet.js
│ │ ├── profileSetOnce.js
│ │ ├── profileUnset.js
│ │ ├── registerSuperProperties.js
│ │ ├── registerSuperProperty.js
│ │ ├── reset.js
│ │ ├── startUp.js
│ │ ├── track.js
│ │ └── unRegisterSuperProperty.js
├── configure
│ ├── base
│ │ ├── fieldRules.js
│ │ ├── fieldTemplate.js
│ │ ├── index.js
│ │ └── lifecycle.js
│ ├── customized
│ │ ├── UA
│ │ │ ├── configure
│ │ │ │ ├── fieldRules.js
│ │ │ │ └── fieldTemplate.js
│ │ │ └── index.js
│ │ ├── decodeGBK
│ │ │ ├── configure
│ │ │ │ └── lifecycle.js
│ │ │ ├── index.js
│ │ │ └── lib
│ │ │ │ └── decodeGBK.js
│ │ ├── encrypt
│ │ │ ├── configure
│ │ │ │ ├── fieldRules.js
│ │ │ │ ├── fieldTemplate.js
│ │ │ │ └── lifecycle.js
│ │ │ ├── index.js
│ │ │ └── lib
│ │ │ │ ├── base64js.min.js
│ │ │ │ └── encrypt.js
│ │ ├── exposure
│ │ │ └── index.js
│ │ ├── heatmap
│ │ │ ├── configure
│ │ │ │ ├── fieldRules.js
│ │ │ │ ├── fieldTemplate.js
│ │ │ │ └── lifecycle.js
│ │ │ ├── heatmapSDK
│ │ │ │ ├── common
│ │ │ │ │ ├── config.js
│ │ │ │ │ ├── iframeMsg.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── head
│ │ │ │ │ ├── heatmap.css
│ │ │ │ │ └── index.js
│ │ │ │ ├── heatElement
│ │ │ │ │ └── heatElement.js
│ │ │ │ ├── heatMap
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── nav.js
│ │ │ │ ├── index.js
│ │ │ │ ├── lib
│ │ │ │ │ ├── colorRange.js
│ │ │ │ │ └── heatmap.js
│ │ │ │ └── webstay
│ │ │ │ │ ├── webStayDom.js
│ │ │ │ │ ├── webStayLine.css
│ │ │ │ │ └── webstay.js
│ │ │ ├── index.js
│ │ │ └── lib
│ │ │ │ ├── elementContent.js
│ │ │ │ ├── getField.js
│ │ │ │ └── heatmap.js
│ │ ├── hybrid
│ │ │ └── lib
│ │ │ │ └── hybrid.js
│ │ ├── mpaas
│ │ │ └── index.js
│ │ ├── pageClose
│ │ │ └── index.js
│ │ ├── userClick
│ │ │ ├── configure
│ │ │ │ ├── fieldRules.js
│ │ │ │ ├── fieldTemplate.js
│ │ │ │ └── lifecycle.js
│ │ │ ├── index.js
│ │ │ └── lib
│ │ │ │ └── userClick.js
│ │ ├── visual
│ │ │ ├── configure
│ │ │ │ ├── fieldRules.js
│ │ │ │ ├── fieldTemplate.js
│ │ │ │ └── lifecycle.js
│ │ │ ├── index.js
│ │ │ ├── lib
│ │ │ │ └── visitor.js
│ │ │ └── visualShow
│ │ │ │ ├── common
│ │ │ │ ├── boxMove.js
│ │ │ │ ├── config.js
│ │ │ │ ├── iframeMsg.js
│ │ │ │ └── index.js
│ │ │ │ ├── debug
│ │ │ │ └── index.js
│ │ │ │ ├── index.js
│ │ │ │ ├── templete
│ │ │ │ ├── debug.js
│ │ │ │ ├── index.js
│ │ │ │ └── style.css
│ │ │ │ └── visual
│ │ │ │ └── index.js
│ │ └── webstay
│ │ │ ├── configure
│ │ │ ├── fieldRules.js
│ │ │ ├── fieldTemplate.js
│ │ │ └── lifecycle.js
│ │ │ ├── index.js
│ │ │ └── lib
│ │ │ ├── autoWebstay.js
│ │ │ └── getField.js
│ └── index.js
├── lib
│ ├── baseConfig
│ │ └── index.js
│ ├── checkField
│ │ └── index.js
│ ├── common
│ │ └── index.js
│ ├── compatible
│ │ ├── JSON2.js
│ │ └── index.js
│ ├── fillField
│ │ ├── UTM.js
│ │ ├── deviceType.js
│ │ ├── getField.js
│ │ ├── id.js
│ │ ├── index.js
│ │ ├── sessionId.js
│ │ └── spider.js
│ ├── mergeRules
│ │ └── index.js
│ ├── printLog
│ │ └── index.js
│ ├── storage
│ │ └── index.js
│ └── upload
│ │ ├── ajax.js
│ │ ├── hybrid.js
│ │ └── index.js
└── main.js
├── vue-demo
├── .gitignore
├── README.md
├── babel.config.js
├── package.json
├── public
│ ├── AnalysysAgent_JS_SDK_HEATMAP.min.js
│ ├── favicon.ico
│ ├── index.html
│ └── js
│ │ └── sdk
│ │ ├── AnalysysAgent_JS_SDK_HEATMAP.min.js
│ │ └── AnalysysAgent_JS_SDK_VISUAL.min.js
├── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ ├── index.vue
│ │ └── next.vue
│ ├── main.js
│ ├── routes
│ │ └── index.js
│ └── sdk
│ │ ├── AnalysysAgent_Encrypt.es6.min.js
│ │ ├── AnalysysAgent_ExposurePoint.es6.min.js
│ │ ├── AnalysysAgent_GBK.es6.min.js
│ │ ├── AnalysysAgent_JS_SDK.es6.min.js
│ │ ├── AnalysysAgent_MPAAS.es6.min.js
│ │ └── AnalysysAgent_PageViewStayTime.es6.min.js
└── vue.config.js
└── vue-dome
└── src
└── sdk
└── AnalysysAgent_MPAAS.es6.min.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "test": {
4 | "plugins": [
5 | "@babel/plugin-transform-modules-commonjs"
6 | ]
7 | }
8 | }
9 | }
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/*
2 | ua-parser.js
3 | test/
4 | **/decodeGBK.js
5 | **/JSON2.js
6 | !src/
7 | *.html
8 | *.json
9 | *.min.js
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "env": {
3 | "browser": true,
4 | "es6": true,
5 | "jest": true,
6 | "node": true
7 | },
8 | "extends": "eslint:recommended",
9 | "globals": {
10 | "Atomics": "readonly",
11 | "SharedArrayBuffer": "readonly",
12 | "__static": true
13 | },
14 | "parser": 'babel-eslint',
15 | "parserOptions": {
16 | "ecmaVersion": 6,
17 | "sourceType": "module",
18 | },
19 | "rules": {
20 | "no-empty": 0,
21 | "no-control-regex": "off",
22 | "no-misleading-character-class": "off"
23 | }
24 | };
--------------------------------------------------------------------------------
/.github/workflows/npm-publish.yml:
--------------------------------------------------------------------------------
1 | name: Node.js Package
2 |
3 | on:
4 | release:
5 | types: [created]
6 |
7 | jobs:
8 | publish-npm:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v2
12 | - uses: actions/setup-node@v1
13 | with:
14 | node-version: 12
15 | registry-url: https://registry.npmjs.org/
16 | - run: npm publish
17 | env:
18 | NODE_AUTH_TOKEN: ${{secrets.npm_token}}
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | package-lock.json
2 | node_modules/
3 | *.zip
4 | .DS_Store
5 | yarn.lock
6 | bac
7 | demo/react/
8 | demo/vue/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Analysys JavaScript SDK [![NPM version][npm-image]][npm-url] [](https://github.com/analysys/ans-javascript-sdk/blob/master/LICENSE) [](https://github.com/analysys/ans-javascript-sdk/releases)
3 |
4 | ========
5 |
6 | This is the official JavaScript SDK for Analysys.
7 |
8 | # JavaScript SDK目录说明:
9 | * demo——API调用演示
10 | * SDK——SDK文件
11 | * src——SDK源码
12 | * vue-demo——VUE框架API调用演示
13 |
14 | # 安装
15 |
16 | ```
17 | npm install ans-javascript-sdk --save
18 | ```
19 |
20 | # JavaScript 基础说明:
21 |
22 | JS SDK 用于由 HTML 、 Css 及 Javascript 制作成的网站,集成前请先安装SDK
23 |
24 | ## 快速集成
25 | 如果您是第一次使用易观方舟产品,可以通过阅读本文快速了解此产品
26 | 1. 选择集成方式
27 | 目前我们提供了异步集成、同步集成的方式
28 | 2. 设置初始化接口
29 | 通过初始化代码的配置参数配置您的 AppKey
30 | 3. 设置上传地址
31 | 通过初始化代码的配置参数 uploadURL 设置您上传数据的地址。
32 | 4. 设置需要采集的页面或事件
33 | 通过手动埋点,设置需要采集的页面或事件。
34 | 5. 打开Debug模式查看日志
35 | 通过设置 Ddebug 模式,开(debugMode为1或2)/关(debugMode为0或不设置) log 查看日志。
36 |
37 | > 通过以上步骤您即可验证SDK是否已经集成成功,具体使用方法参考:[易观方舟 JavaScript SDK 文档](https://docs.analysys.cn/ark/integration/sdk/js/js)
38 |
39 | > 注意 SDK 可能不完全向前兼容,请查看版本更新说明 [Release及版本升级记录](https://github.com/analysys/ans-javascript-sdk/releases)。如果有说明不兼容的话,需要升级易观方舟对应的版本。 请根据需要前往 [Release](https://github.com/analysys/ans-javascript-sdk/releases) 里下载对应的文件
40 |
41 | ## 版本升级记录
42 | 请参见 [Release及版本升级记录](https://github.com/analysys/ans-wechat-sdk/releases)
43 | 更多Api使用方法参考:[易观方舟 JavaScript SDK 文档](https://docs.analysys.cn/ark/integration/sdk/js/js)
44 |
45 | # 讨论
46 | * 微信号:nlfxwz
47 | * 钉钉群:30099866
48 | * 邮箱:nielifeng@analysys.com.cn
49 |
50 |
51 | # License
52 |
53 | [gpl-3.0](https://www.gnu.org/licenses/gpl-3.0.txt)
54 |
55 | **禁止一切基于易观方舟 javascript 开源 SDK 的所有商业活动!**
56 |
57 | ---
58 |
59 | [![NPM downloads][npm-downloads]][npm-url]
60 |
61 |
62 | [homepage]: https://github.com/analysys/ans-javascript-sdk
63 | [npm-url]: https://www.npmjs.com/package/ans-javascript-sdk
64 | [npm-image]: https://img.shields.io/npm/v/ans-javascript-sdk.svg?style=flat
65 | [npm-downloads]: https://img.shields.io/npm/dm/ans-javascript-sdk.svg?style=flat
66 |
--------------------------------------------------------------------------------
/demo/javascript/initSdk.js:
--------------------------------------------------------------------------------
1 | (function (c) {
2 | window.AnalysysAgent = window.AnalysysAgent || {}
3 | var a = window.AnalysysAgent || {}
4 | var ans = ['identify', 'alias', 'reset', 'track', 'profileSet', 'profileSetOnce', 'profileIncrement', 'profileAppend', 'profileUnset', 'profileDelete', 'registerSuperProperty', 'registerSuperProperties', 'unRegisterSuperProperty', 'clearSuperProperties', 'getSuperProperty', 'getSuperProperties', 'pageView', 'getDistinctId']
5 | a['config'] = c
6 | a['param'] = []
7 | function factory (b) {
8 | return function () {
9 | a['param'].push([b, arguments])
10 | return window.AnalysysAgent
11 | }
12 | }
13 | for (var i = 0; i < ans.length; i++) {
14 | a[ans[i]] = factory(ans[i])
15 | }
16 | if (c.name) {
17 | window[c.name] = a
18 | }
19 | })({
20 | appkey: "commondebug", //APPKEY
21 | debugMode: 2,
22 | uploadURL: 'https://sdk.analysys.cn:4089/',
23 | visitorConfigURL: 'https://sdk.analysys.cn:4089/',
24 | /**如无自定义配置,则与uploadURL相同**/
25 | autoHeatmap: true
26 | })
--------------------------------------------------------------------------------
/demo/style/console.js:
--------------------------------------------------------------------------------
1 | console.oldLog = console.log
2 | console.log = a = function () {
3 | if (console.constructor === Object && console.log) {
4 | try {
5 | console.oldLog.apply(console, arguments);
6 | } catch (e) {
7 | console.oldLog(arguments[0]);
8 | }
9 | }
10 | // console.log(arguments)
11 | if (arguments[0] && arguments[0].constructor === String && arguments[0].indexOf("Send") > -1) {
12 | try {
13 | document.getElementById("upLog").innerText = arguments[0]
14 | } catch (e) {}
15 | }
16 | }
--------------------------------------------------------------------------------
/demo/style/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * [pageView description] 页面事件
3 | * @param {[String]} pageName [description] 页面标识,支持类型:String;最大长度255字符
4 | * @param {[Object]} pageInfo [description] 页面信息,支持类型:Object/Array;页面信息最多包含100条;Object类型内key以字母或$开头,包括大小写字母、数字、下划线和$,最大长度125字符,不支持乱码和中文;Object/Array中的value,支持类型:String;则最大长度255字符
5 | */
6 | function pageView(pageName, pageInfo) {
7 | AnalysysAgent.pageView(pageName, pageInfo)
8 | }
9 | /**
10 | * [track description] 点击事件
11 | * @param {[String]} eventName [description] 事件名称。支持类型:String。以字母或$开头,可以包含大小写字母/数字/下划线,不支持中文,不支持乱码,最大长度99字符。
12 | * @param {[Object]} eventInfo [description] 事件属性,支持类型:Object/Array;事件属性最多包含100条;Object类型内key以字母或$开头,包括大小写字母、数字、下划线和$,最大长度125字符,不支持乱码和中文;Object/Array中的value,支持类型:String;则最大长度255字符
13 | */
14 | function track(eventName, eventInfo) {
15 | AnalysysAgent.track(eventName, eventInfo);
16 | }
17 | /**
18 | * [registerSuperProperty description] 注册通用属性
19 | * @param {[String]} uperPropertyName [description] 属性名称 支持类型:String。以字母或$开头,可以包含大小写字母/数字/下划线,不支持中文,不支持乱码,最大长度99字符。
20 | * @param {[String]} superPropertyValue [description] 事件属性,支持类型:String;则最大长度255字符
21 | */
22 | function registerSuperProperty(superPropertyName, superPropertyValue) {
23 | AnalysysAgent.registerSuperProperty(superPropertyName, superPropertyValue);
24 | }
25 |
26 | /**
27 | * [registerSuperProperties description] 注册通用属性
28 | * @param {[Object]} superProperties [description] 属性集合 支持类型:Object。key以字母或$开头,可以包含大小写字母/数字/下划线,不支持中文,不支持乱码,最大长度99字符,value支持类型:String;则最大长度255字符。
29 | */
30 | function registerSuperProperties(superProperties) {
31 | AnalysysAgent.registerSuperProperties(superProperties);
32 | }
33 | /**
34 | * [unregisterSuperProperty description] 删除单个通用属性
35 | * @param {[Object]} superPropertyName [description] 属性名称 支持类型:String。以字母或$开头,可以包含大小写字母/数字/下划线,不支持中文,不支持乱码,最大长度99字符。
36 | */
37 | function unRegisterSuperProperty(superPropertyName) {
38 | AnalysysAgent.unRegisterSuperProperty(superPropertyName);
39 | }
40 | /**
41 | * [clearSuperProperties description] 清除所有通用属性
42 | */
43 | function clearSuperProperties() {
44 | AnalysysAgent.clearSuperProperties();
45 | }
46 | /**
47 | * [clearSuperProperties description] 获取单个通用属性
48 | */
49 | function getSuperProperty(superPropertyName) {
50 | var superProperty = AnalysysAgent.getSuperProperty(superPropertyName);
51 | console.log('获取单个通用属性[' + superPropertyName + ']:', superProperty)
52 | }
53 | /**
54 | * [clearSuperProperties description] 获取所有通用属性
55 | */
56 | function getSuperProperties() {
57 | var superProperties = AnalysysAgent.getSuperProperties();
58 | console.log('获取所有通用属性:', superProperties)
59 | }
60 | /**
61 | * [identify description] 用户ID设置
62 | * @param {[String]} distinctId [description] 唯一身份标识,支持类型:String;长度大于0且小于255字符
63 | */
64 | function identify(distinctId) {
65 | AnalysysAgent.identify(distinctId);
66 | }
67 | /**
68 | * [alias description]用户关联 新distinctID关联到原有originalID,originalID为原始id.
69 | * @param {[String]} aliasId [description] 支持类型:String;长度大于0,且小于255字符
70 | */
71 | function alias(aliasId) {
72 | AnalysysAgent.alias(aliasId);
73 | }
74 | /**
75 | * [profileSet description] 设置用户属性
76 | * @param {[String]} propertyName [description] 支持类型:String;以字母或`$`开头,可包含大小写字母/数字/`_`/`$`,最大长度125字符,不支持乱码和中文
77 | * @param {[String/Number/Boolean/Array]} propertyValue [description]支持类型:String/Number/Boolean/Array;若为字符串,则最大长度255字符;若为数组或集合,则最多包含100条,且key约束条件与属性名称一致,value最大长度255字符
78 | */
79 | function profileSet(propertyName, propertyValue) {
80 | AnalysysAgent.profileSet(propertyName, propertyValue);
81 | }
82 | /**
83 | * [profileSetOnce description] 在首次设置时有效的属性
84 | * @param {[String]} propertyName [description] 支持类型:String;以字母或`$`开头,可包含大小写字母/数字/`_`/`$`,最大长度125字符,不支持乱码和中文
85 | * @param {[String/Number/Boolean/Array]} propertyValue [description] 支持类型:String/Number/Boolean/Array;若为字符串,则最大长度255字符;若为数组或集合,则最多包含100条,且key约束条件与属性名称一致,value最大长度255字符
86 | */
87 | function profileSetOnce(propertyName, propertyValue) {
88 | AnalysysAgent.profileSetOnce(propertyName, propertyValue);
89 | }
90 | /**
91 | * [profileIncrement description] 设置用户属性相对变化值
92 | * @param {[String]} propertyName [description] 属性名称 支持类型:String;以字母或`$`开头,可包含大小写字母/数字/`_`/`$`,最大长度125字符,不支持乱码和中文
93 | * @param {[String/Number/Boolean/Array]} propertyValue [description] 属性值 支持类型:String/Number/Boolean/Array;若为字符串,则最大长度255字符;若为数组或集合,则最多包含100条,且key约束条件与属性名称一致,value最大长度255字符
94 | */
95 | function profileIncrement(propertyName, propertyValue) {
96 | AnalysysAgent.profileIncrement(propertyName, propertyValue)
97 | }
98 | /**
99 | * [profileAppend description]设置单个列表类型的属性
100 | * @param {[String]} propertyName [description] 属性名称 支持类型:String;以字母或`$`开头,可包含大小写字母/数字/`_`/`$`,最大长度125字符,不支持乱码和中文
101 | * @param {[String/Number/Boolean]} propertyValue [description] 属性值 支持类型:String/Number/Boolean;最大长度255字符;
102 | */
103 | function profileAppend(propertyName, propertyValue) {
104 | AnalysysAgent.profileAppend(propertyName, propertyValue);
105 | }
106 | /**
107 | * [profileUnset description] 删除设置的属性
108 | * @param {[String]} property [description] 属性名称 支持类型:String;以字母或`$`开头,可包含大小写字母/数字/`_`/`$`,最大长度125字符,不支持乱码和中文
109 | */
110 | function profileUnset(property) {
111 | AnalysysAgent.profileUnset(property);
112 | }
113 | /**
114 | * [profileDelete description] 要清除已经设置的所有属性
115 | */
116 | function profileDelete() {
117 | AnalysysAgent.profileDelete();
118 | }
119 | /**
120 | * [reset description] 清除本地设置
121 | */
122 | function reset() {
123 | AnalysysAgent.reset();
124 | }
125 |
126 | /**
127 | * [historyPage description] 修改history记录跳转页面
128 | * @param {[String]} page [description] 跳转页面地址
129 | */
130 | function historyPage(page) {
131 | document.title = 'historyPage' //跳转后的页面title
132 | history.pushState(null, null, page)
133 | }
134 | /**
135 | * [historyPage description] 修改hash值跳转页面
136 | * @param {[String]} page [description] 跳转页面地址
137 | */
138 | function hashPage(page) {
139 | document.title = 'hashPage'
140 | location.href = page
141 | }
142 |
143 | /**
144 | * 获取预置属性
145 | */
146 | function getPresetProperties() {
147 | var presetProperties = AnalysysAgent.getPresetProperties()
148 | console.log('获取预置属性:', presetProperties)
149 | }
150 |
151 | /**
152 | * 获取匿名ID
153 | */
154 | function getDistinctId() {
155 | var distinctId = AnalysysAgent.getDistinctId()
156 | console.log("匿名ID:" + distinctId)
157 | }
--------------------------------------------------------------------------------
/demo/style/plugIn/bootstrap/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analysys/ans-javascript-sdk/83a214c8c92f79557107d105c67223b7c32632ee/demo/style/plugIn/bootstrap/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/demo/style/plugIn/bootstrap/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analysys/ans-javascript-sdk/83a214c8c92f79557107d105c67223b7c32632ee/demo/style/plugIn/bootstrap/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/demo/style/plugIn/bootstrap/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analysys/ans-javascript-sdk/83a214c8c92f79557107d105c67223b7c32632ee/demo/style/plugIn/bootstrap/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/demo/style/plugIn/bootstrap/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analysys/ans-javascript-sdk/83a214c8c92f79557107d105c67223b7c32632ee/demo/style/plugIn/bootstrap/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/demo/style/plugIn/bootstrap/js/npm.js:
--------------------------------------------------------------------------------
1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
2 | require('../../js/transition.js')
3 | require('../../js/alert.js')
4 | require('../../js/button.js')
5 | require('../../js/carousel.js')
6 | require('../../js/collapse.js')
7 | require('../../js/dropdown.js')
8 | require('../../js/modal.js')
9 | require('../../js/tooltip.js')
10 | require('../../js/popover.js')
11 | require('../../js/scrollspy.js')
12 | require('../../js/tab.js')
13 | require('../../js/affix.js')
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ans-javascript-sdk",
3 | "version": "4.5.6",
4 | "description": "official analysysAgent javascript sdk",
5 | "main": "./sdk/AnalysysAgent_JS_SDK.min.js",
6 | "module": "./sdk/AnalysysAgent_JS_SDK.es6.min.js",
7 | "scripts": {
8 | "test": "jest",
9 | "dev": "rollup -c rollup.config.js --watch",
10 | "module": "rollup -c rollup.module.config.js --watch",
11 | "plugins": "rollup -c rollup.plugins.config.js --watch",
12 | "build": "rollup -c rollup.config.js&&rollup -c rollup.module.config.js&&rollup -c rollup.plugins.config.js",
13 | "cover": "jest --coverage",
14 | "lint": "standard \"src/**/*.{js,vue}\"",
15 | "lint:fix": "standard \"src/**/*.{js,vue}\" --fix"
16 | },
17 | "repository": {
18 | "type": "git",
19 | "url": "git+https://github.com/analysys/ans-javascript-sdk.git"
20 | },
21 | "standard": {
22 | "parser": "babel-eslint",
23 | "rules": {
24 | "no-control-regex": "off",
25 | "no-misleading-character-class": "off"
26 | },
27 | "ignore": [
28 | "**/parseUA/**",
29 | "test/",
30 | "decodeGBK.js",
31 | "**/lib/heatmap.js",
32 | "JSON2.js",
33 | "**/upload/index.js",
34 | "*.html",
35 | "*.json"
36 | ]
37 | },
38 | "author": "zhangyufei@analysys.com.cn",
39 | "license": "ISC",
40 | "devDependencies": {
41 | "@babel/cli": "^7.10.0",
42 | "@babel/core": "^7.10.0",
43 | "@babel/helpers": "^7.7.0",
44 | "@babel/plugin-external-helpers": "^7.8.3",
45 | "@babel/plugin-proposal-class-properties": "^7.7.0",
46 | "@babel/plugin-proposal-decorators": "^7.7.0",
47 | "@babel/plugin-proposal-export-namespace-from": "^7.0.0",
48 | "@babel/plugin-proposal-function-sent": "^7.7.0",
49 | "@babel/plugin-proposal-json-strings": "^7.0.0",
50 | "@babel/plugin-proposal-numeric-separator": "^7.0.0",
51 | "@babel/plugin-proposal-throw-expressions": "^7.0.0",
52 | "@babel/plugin-syntax-dynamic-import": "^7.0.0",
53 | "@babel/plugin-syntax-import-meta": "^7.0.0",
54 | "@babel/plugin-transform-reserved-words": "^7.2.0",
55 | "@babel/plugin-transform-runtime": "^7.0.0",
56 | "@babel/preset-env": "^7.10.0",
57 | "@babel/register": "^7.7.0",
58 | "babel-core": "^7.0.0-bridge.0",
59 | "babel-eslint": "^10.0.3",
60 | "babel-jest": "^26.0.1",
61 | "babel-loader": "^8.1.0",
62 | "babel-plugin-transform-member-expression-literals": "^6.9.4",
63 | "babel-plugin-transform-property-literals": "^6.9.4",
64 | "babel-preset-es2015": "^6.24.1",
65 | "babel-preset-es2015-rollup": "~3.0.0",
66 | "babel-preset-es3": "~1.0.1",
67 | "babel-preset-stage-2": "^6.24.1",
68 | "eslint": "^7.1.0",
69 | "heatmap.js": "^2.0.5",
70 | "jest": "^26.0.1",
71 | "pako": "^1.0.10",
72 | "rollup-plugin-babel": "^4.0.1",
73 | "rollup-plugin-commonjs": "^10.1.0",
74 | "rollup-plugin-es3": "^1.1.0",
75 | "rollup-plugin-eslint": "^7.0.0",
76 | "rollup-plugin-json": "^4.0.0",
77 | "rollup-plugin-node-builtins": "~2.1.2",
78 | "rollup-plugin-node-resolve": "^5.2.0",
79 | "rollup-plugin-postcss": "^3.1.1",
80 | "rollup-plugin-replace": "^2.2.0",
81 | "rollup-plugin-terser": "^6.1.0",
82 | "rollup-plugin-uglify": "^6.0.3",
83 | "rollup-watch": "~4.3.1",
84 | "ua-device": "^0.1.10"
85 | },
86 | "dependencies": {
87 | "@babel/plugin-proposal-do-expressions": "^7.0.0",
88 | "@babel/plugin-proposal-export-default-from": "^7.0.0",
89 | "@babel/plugin-proposal-export-namespace-from": "^7.0.0",
90 | "@babel/plugin-proposal-function-bind": "^7.0.0",
91 | "@babel/plugin-proposal-json-strings": "^7.0.0",
92 | "@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
93 | "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
94 | "@babel/plugin-proposal-numeric-separator": "^7.0.0",
95 | "@babel/plugin-proposal-optional-chaining": "^7.0.0",
96 | "@babel/plugin-proposal-pipeline-operator": "^7.0.0",
97 | "@babel/plugin-proposal-throw-expressions": "^7.0.0",
98 | "@babel/plugin-syntax-dynamic-import": "^7.0.0",
99 | "@babel/plugin-syntax-import-meta": "^7.0.0",
100 | "@babel/plugin-transform-member-expression-literals": "^7.0.0",
101 | "@babel/plugin-transform-modules-commonjs": "^7.10.4",
102 | "@babel/plugin-transform-property-literals": "^7.0.0",
103 | "@babel/polyfill": "^7.8.7",
104 | "@babel/runtime": "^7.7.2",
105 | "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
106 | "babel-preset-env": "^1.7.0",
107 | "core-js": "^3.6.5",
108 | "crypto-js": "^3.1.9-1",
109 | "intersection-observer": "^0.11.0",
110 | "mutationobserver-shim": "^0.3.7",
111 | "regenerator-runtime": "^0.13.3",
112 | "rollup": "^1.27.3"
113 | },
114 | "bugs": {
115 | "url": "https://github.com/analysys/ans-javascript-sdk/issues"
116 | },
117 | "homepage": "https://github.com/analysys/ans-javascript-sdk#readme",
118 | "keywords": [
119 | "analysys",
120 | "analysysagent",
121 | "ans",
122 | "analytics",
123 | "sdk",
124 | "js"
125 | ],
126 | "engines": {
127 | "node": ">=6.0"
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import babel from 'rollup-plugin-babel'
2 | import { eslint } from 'rollup-plugin-eslint'
3 | import resolve from 'rollup-plugin-node-resolve'
4 | import commonjs from 'rollup-plugin-commonjs'
5 | import postcss from 'rollup-plugin-postcss'
6 | import { uglify } from 'rollup-plugin-uglify'
7 | import { terser } from 'rollup-plugin-terser'
8 | import es3 from 'rollup-plugin-es3';
9 | export default [
10 | {
11 | input: './src/main.js',
12 | output: [
13 | {
14 | file: './demo/sdk/AnalysysAgent_JS_SDK.min.js',
15 | format: 'umd',
16 | name: 'AnalysysAgent',
17 | freeze: false,
18 | plugins: [
19 | uglify({
20 | mangle: {
21 | toplevel: true
22 | },
23 | ie8: true
24 | })
25 | ],
26 | amd: {
27 | define: '{}'
28 | }
29 | },
30 | {
31 | file: './SDK/AnalysysAgent_JS_SDK.min.js',
32 | format: 'umd',
33 | name: 'AnalysysAgent',
34 | freeze: false,
35 | plugins: [
36 | uglify({
37 | mangle: {
38 | toplevel: true
39 | },
40 | ie8: true
41 | })
42 | ],
43 | amd: {
44 | define: '{}'
45 | }
46 | },
47 | {
48 | file: './demo/sdk/AnalysysAgent_JS_SDK.amd.min.js',
49 | format: 'amd',
50 | name: 'AnalysysAgent',
51 | freeze: false,
52 | plugins: [
53 | uglify({
54 | mangle: {
55 | toplevel: true
56 | },
57 | ie8: true
58 | })
59 | ]
60 | }, {
61 | file: './SDK/AnalysysAgent_JS_SDK.es6.min.js',
62 | format: 'esm',
63 | name: 'AnalysysAgent',
64 | plugins: [
65 | terser({
66 | mangle: {
67 | toplevel: true
68 | }
69 | })
70 | ]
71 | },
72 | {
73 | file: './vue-demo/src/sdk/AnalysysAgent_JS_SDK.es6.min.js',
74 | format: 'esm',
75 | name: 'AnalysysAgent',
76 | freeze: false,
77 | plugins: [
78 | terser({
79 | mangle: {
80 | toplevel: true
81 | }
82 | })
83 | ]
84 | }
85 | ],
86 | plugins: [
87 | resolve({
88 | jsnext: true,
89 | main: true,
90 | browser: true
91 | }),
92 | postcss({
93 | extensions: ['.css']
94 | }),
95 | commonjs(),
96 | eslint({
97 | include: 'src/**',
98 | exclude: ['node_modules/**'],
99 | }),
100 | babel({
101 |
102 | babelrc: false,
103 |
104 | presets: [['@babel/preset-env', {
105 | modules: false, loose: true, "targets": {
106 | "ie": "6"
107 | }
108 | }]],
109 |
110 | include: ['src/**'],
111 |
112 | plugins: ['@babel/plugin-external-helpers'],
113 |
114 | runtimeHelpers: true
115 |
116 | }),
117 |
118 | es3({
119 |
120 | remove: ['defineProperty', 'freeze']
121 |
122 | })
123 | ]
124 | }
125 | ]
126 |
--------------------------------------------------------------------------------
/rollup.plugins.config.js:
--------------------------------------------------------------------------------
1 | import babel from 'rollup-plugin-babel'
2 | import { eslint } from 'rollup-plugin-eslint'
3 | import resolve from 'rollup-plugin-node-resolve'
4 | import commonjs from 'rollup-plugin-commonjs'
5 | import postcss from 'rollup-plugin-postcss'
6 | import es3 from 'rollup-plugin-es3';
7 | import { uglify } from 'rollup-plugin-uglify'
8 | import { terser } from 'rollup-plugin-terser'
9 | var plugin = [
10 | resolve({
11 | jsnext: true,
12 | main: true,
13 | browser: true
14 | }),
15 | postcss({
16 | extensions: ['.css']
17 | }),
18 | commonjs(),
19 | eslint({
20 | include: 'src/**',
21 | exclude: ['node_modules/**'],
22 | }),
23 | babel({
24 |
25 | babelrc: false,
26 |
27 | presets: [['@babel/preset-env', {
28 | modules: false, loose: true, "targets": {
29 | "ie": "6"
30 | }
31 | }]],
32 |
33 | include: ['src/**'],
34 |
35 | plugins: ['@babel/plugin-external-helpers'],
36 |
37 | runtimeHelpers: true
38 |
39 | }),
40 |
41 | es3({
42 |
43 | remove: ['defineProperty', 'freeze']
44 |
45 | })
46 | ]
47 | export default [
48 | {
49 | input: './src/configure/customized/mpaas/index.js',
50 | output: [{
51 | file: './demo/sdk/AnalysysAgent_MPAAS.min.js',
52 | format: 'iife',
53 | name: 'Encrypt',
54 | freeze: false, // 禁止使用Object.freeze方式加载模块
55 | plugins: [
56 | uglify({
57 | mangle: {
58 | toplevel: true
59 | },
60 | ie8: true
61 | })
62 | ]
63 | },
64 | {
65 | file: './sdk/AnalysysAgent_MPAAS.min.js',
66 | format: 'iife',
67 | name: 'Encrypt',
68 | freeze: false, // 禁止使用Object.freeze方式加载模块
69 | plugins: [
70 | uglify({
71 | mangle: {
72 | toplevel: true
73 | },
74 | ie8: true
75 | })
76 | ]
77 | }, {
78 | file: './vue-dome/src/sdk/AnalysysAgent_MPAAS.es6.min.js',
79 | format: 'esm',
80 | name: 'Encrypt',
81 | plugins: [
82 | terser({
83 | mangle: {
84 | toplevel: true
85 | }
86 | })
87 | ]
88 | },
89 | {
90 | file: './sdk/AnalysysAgent_MPAAS.es6.min.js',
91 | format: 'esm',
92 | name: 'Encrypt',
93 | plugins: [
94 | terser({
95 | mangle: {
96 | toplevel: true
97 | }
98 | })
99 | ]
100 | },
101 | {
102 | file: './demo/sdk/AnalysysAgent_MPAAS.amd.min.js',
103 | format: 'amd',
104 | name: 'Encrypt',
105 | plugins: [
106 | uglify({
107 | mangle: {
108 | toplevel: true
109 | },
110 | ie8: true
111 | })
112 | ]
113 | },
114 | {
115 | file: './sdk/AnalysysAgent_MPAAS.amd.min.js',
116 | format: 'amd',
117 | name: 'Encrypt',
118 | plugins: [
119 | uglify({
120 | mangle: {
121 | toplevel: true
122 | },
123 | ie8: true
124 | })
125 | ]
126 | }],
127 | plugins: plugin
128 | }
129 | ]
130 |
--------------------------------------------------------------------------------
/sdk/md5.txt:
--------------------------------------------------------------------------------
1 | AnalysysAgent_Encrypt.amd.min.js : 784433ef6b1f4f6b040ddb566aea0626
2 | AnalysysAgent_Encrypt.es6.min.js : 6a2ee50777d35badecafb442cd38d0a1
3 | AnalysysAgent_Encrypt.min.js : 9053fda19b72f6226960a6bbabc2d2f7
4 | AnalysysAgent_ExposurePoint.amd.min.js : 5ed0d2ef918f77cdf10a343287971bc0
5 | AnalysysAgent_ExposurePoint.es6.min.js : b9c117d8d584443c551bc13cb6783a6f
6 | AnalysysAgent_ExposurePoint.min.js : 69d54c00a1d4d4ebe5d382b720be274a
7 | AnalysysAgent_GBK.amd.min.js : 1b93e2c1ad648a1f85bcd5a11a4d2ef5
8 | AnalysysAgent_GBK.es6.min.js : cba14fe216ea5cda5b1585ad5e9d8ee5
9 | AnalysysAgent_GBK.min.js : 2c2573fd9a7570a4dda6f9561eb3c3c6
10 | AnalysysAgent_JS_SDK.amd.min.js : 0856ef5489080e0c398e4020b7ec1372
11 | AnalysysAgent_JS_SDK.es6.min.js : 9a3e60cd258c7e81c0f0fb24820ec4a0
12 | AnalysysAgent_JS_SDK.min.js : 377b06e05d8a71de0e47d85f571908b8
13 | AnalysysAgent_JS_SDK_HEATMAP.min.js : 38502d01e3423d36bc29f57a8fb45c3b
14 | AnalysysAgent_JS_SDK_VISUAL.min.js : 775cd61493f4ea9de299226b1029dc32
15 | AnalysysAgent_MPAAS.amd.min.js : cc1899d875c3fd25b0aee7c65cac5bd7
16 | AnalysysAgent_MPAAS.es6.min.js : 662d57935949fdad4f6d19b80b06f15c
17 | AnalysysAgent_MPAAS.min.js : 76c03a094e69cd9fd0c68bf8ee4d70f7
18 | AnalysysAgent_PageViewStayTime.amd.min.js : 739b2a6e10971e9b953bebc42767ac14
19 | AnalysysAgent_PageViewStayTime.es6.min.js : 6b1340d9e6b963cfe99a8b1cd36225cb
20 | AnalysysAgent_PageViewStayTime.min.js : 6b245404a732029f33e120904c64e287
21 |
--------------------------------------------------------------------------------
/src/API/index.js:
--------------------------------------------------------------------------------
1 | // import '../lib/compatible/index.js'
2 | import { pageView } from './template/pageView.js'
3 | import { track } from './template/track.js'
4 | import { freeApi } from './template/freeApi.js'
5 | import { getPresetProperties } from './template/getPresetProperties.js'
6 | import { alias } from './template/alias.js'
7 | import { identify } from './template/identify.js'
8 | import { profileSet } from './template/profileSet.js'
9 | import { profileSetOnce } from './template/profileSetOnce.js'
10 | import { profileIncrement } from './template/profileIncrement.js'
11 | import { profileAppend } from './template/profileAppend.js'
12 | import { profileUnset } from './template/profileUnset.js'
13 | import { profileDelete } from './template/profileDelete.js'
14 | import { registerSuperProperty } from './template/registerSuperProperty.js'
15 | import { registerSuperProperties } from './template/registerSuperProperties.js'
16 | import { getSuperProperty } from './template/getSuperProperty.js'
17 | import { getSuperProperties } from './template/getSuperProperties.js'
18 | import { unRegisterSuperProperty } from './template/unRegisterSuperProperty.js'
19 | import { clearSuperProperties } from './template/clearSuperProperties.js'
20 | import { reset } from './template/reset.js'
21 | // import { push } from './template/push.js'
22 | import { getDistinctId } from './template/getDistinctId.js'
23 |
24 | export {
25 | pageView,
26 | profileSet,
27 | profileSetOnce,
28 | profileIncrement,
29 | profileAppend,
30 | profileUnset,
31 | profileDelete,
32 | alias,
33 | identify,
34 | track,
35 | registerSuperProperty,
36 | registerSuperProperties,
37 | getSuperProperty,
38 | getSuperProperties,
39 | unRegisterSuperProperty,
40 | clearSuperProperties,
41 | reset,
42 | freeApi,
43 | // push,
44 | getDistinctId,
45 | getPresetProperties
46 | }
47 |
--------------------------------------------------------------------------------
/src/API/template/alias.js:
--------------------------------------------------------------------------------
1 | import { temp } from '../../lib/mergeRules/index.js'
2 | import { fillField, checkPrivate, resetCode } from '../../lib/fillField/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import { upLog } from '../../lib/upload/index.js'
5 | import Util from '../../lib/common/index.js'
6 | import Storage from '../../lib/storage/index.js'
7 | import { transporter, backParamsArray } from '../../lib/upload/hybrid.js'
8 | import { successLog } from '../../lib/printLog/index.js'
9 | function alias (aliasId, callback) {
10 | baseConfig.status.FnName = '$alias'
11 | resetCode()
12 | if (aliasId === Storage.getLocal('ARK_LOGINID')) {
13 | baseConfig.status.successCode = '20013'
14 | successLog()
15 | Util.paramType(callback) === 'Function' && callback.call(callback)
16 | return false
17 | }
18 | if (baseConfig.base.isHybrid === true) {
19 | var backParams = backParamsArray(aliasId, '', callback)
20 | var paramArray = backParams.argArray
21 | transporter('alias', paramArray, backParams.callback)
22 | return
23 | }
24 | // 检测aliasId
25 | var status = checkPrivate(aliasId, '$alias', true)
26 |
27 | if (!status) {
28 | Util.paramType(callback) === 'Function' && callback.call(callback)
29 | return
30 | }
31 | // if (distinctId) {
32 | // //检测distinctId
33 | // status = checkPrivate(distinctId, '$alias', true)
34 | // if (status) {
35 | // Storage.setLocal('ARK_TRACKID', distinctId)
36 | // }
37 | // }
38 |
39 | Storage.setLocal('ARK_LOGINID', aliasId)
40 |
41 | var aliasTemp = temp('$alias')
42 | var aliasLog = fillField(aliasTemp)
43 |
44 | // 去除空数据后上传数据
45 | upLog(Util.delEmpty(aliasLog), callback)
46 |
47 | if (baseConfig.base.autoProfile === true) {
48 | baseConfig.status.FnName = '$profile_set_once'
49 | var profileSetOnceTemp = temp('$profile_set_once')
50 |
51 | var profileSetOnceObj = fillField(profileSetOnceTemp)
52 | var time = Storage.getLocal('ARKFRISTPROFILE') || Util.format(new Date(), 'yyyy-MM-dd hh:mm:ss.SSS')
53 | var obj = {
54 | $first_visit_time: time,
55 | $first_visit_language: (navigator.language || navigator.browserLanguage).toLowerCase()
56 | }
57 | var profileSetOnceLog = Util.objMerge(profileSetOnceObj, {
58 | xcontext: obj
59 | })
60 | // 去除空数据后上传数据
61 | upLog(Util.delEmpty(profileSetOnceLog))
62 | Storage.setLocal('ARKFRISTPROFILE', time)
63 | }
64 | }
65 | export {
66 | alias
67 | }
68 |
--------------------------------------------------------------------------------
/src/API/template/clearSuperProperties.js:
--------------------------------------------------------------------------------
1 | import { resetCode } from '../../lib/fillField/index.js'
2 | import { successLog } from '../../lib/printLog/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import Storage from '../../lib/storage/index.js'
5 | import Util from '../../lib/common/index.js'
6 | import { transporter, backParamsArray } from '../../lib/upload/hybrid.js'
7 | function clearSuperProperties (callback) {
8 | baseConfig.status.FnName = '$clearSuperProperties'
9 | resetCode()
10 | if (baseConfig.base.isHybrid === true) {
11 | var backParams = backParamsArray(callback)
12 | var paramArray = backParams.argArray
13 | transporter('clearSuperProperties', paramArray, backParams.callback)
14 | return
15 | }
16 |
17 | Storage.setLocal('ARKSUPER', {})
18 |
19 | baseConfig.status.successCode = '20004'
20 | successLog()
21 | Util.paramType(callback) === 'Function' && callback.call(callback)
22 | }
23 | export { clearSuperProperties }
24 |
--------------------------------------------------------------------------------
/src/API/template/freeApi.js:
--------------------------------------------------------------------------------
1 | import { temp } from '../../lib/mergeRules/index.js'
2 | import { fillField, resetCode } from '../../lib/fillField/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import { upLog } from '../../lib/upload/index.js'
5 | import Util from '../../lib/common/index.js'
6 | import Storage from '../../lib/storage/index.js'
7 | import { transporter, backParamsArray } from '../../lib/upload/hybrid.js'
8 | function freeApi (apiName, property) {
9 |
10 | baseConfig.status.FnName = apiName
11 | resetCode()
12 | var freeApiTemp = temp(apiName)
13 | if (!freeApiTemp) {
14 | return
15 | }
16 | if (baseConfig.base.isHybrid === true) {
17 | var hybridTemp = temp(apiName + 'base')
18 | var hybridLog = fillField(hybridTemp)
19 | var log = Util.delNotHybrid(Util.delEmpty(hybridLog.xcontext))
20 |
21 | var backParams = backParamsArray(apiName, log)
22 | var paramArray = backParams.argArray
23 | transporter('track', paramArray)
24 | return
25 | }
26 | var freeApiLog = fillField(freeApiTemp)
27 | var arkSuper = Storage.getLocal('ARKSUPER') || {}
28 | if (Util.paramType(property) === 'Object') {
29 | arkSuper = Util.objMerge(arkSuper, property)
30 | }
31 | freeApiLog = Util.objMerge(freeApiLog, { xcontext: arkSuper }, {arrMerge: false})
32 |
33 | upLog(Util.delEmpty(freeApiLog))
34 | }
35 | export { freeApi }
36 |
--------------------------------------------------------------------------------
/src/API/template/getDistinctId.js:
--------------------------------------------------------------------------------
1 | import { getUUId, getIdentifyId } from '../../lib/fillField/id.js'
2 | import Util from '../../lib/common/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import { transporter } from '../../lib/upload/hybrid.js'
5 | function getDistinctId (callback) {
6 | if (baseConfig.base.isHybrid === true) {
7 | var callbackFn = 'AnsCallback' + +new Date()
8 | window[callbackFn] = function () {
9 | callback.apply(callback, arguments)
10 | delete window[callbackFn]
11 | }
12 | transporter('getDistinctId', [], callbackFn)
13 | return
14 | }
15 | var id = getIdentifyId() || getUUId()
16 | if (Util.paramType(callback) === 'Function') {
17 | callback.call(callback, id)
18 | }
19 | return id
20 | }
21 | export { getDistinctId }
22 |
--------------------------------------------------------------------------------
/src/API/template/getPresetProperties.js:
--------------------------------------------------------------------------------
1 | import { temp } from '../../lib/mergeRules/index.js'
2 | import { fillField, resetCode } from '../../lib/fillField/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import Util from '../../lib/common/index.js'
5 | import Storage from '../../lib/storage/index.js'
6 | import { transporter } from '../../lib/upload/hybrid.js'
7 | function getPresetProperties (callback) {
8 | baseConfig.status.FnName = '$getPresetProperties'
9 | resetCode()
10 | if (baseConfig.base.isHybrid === true) {
11 | var callbackFn = 'AnsCallback' + +new Date()
12 | window[callbackFn] = function () {
13 | callback.apply(callback, arguments)
14 | delete window[callbackFn]
15 | }
16 | transporter('getPresetProperties', [], callbackFn)
17 | return
18 | }
19 | // 检测aliasId
20 | var getPresetPropertiesTemp = temp('$getPresetProperties')
21 | var getPresetPropertiesLog = fillField(getPresetPropertiesTemp)
22 | getPresetPropertiesLog.xcontext.$first_visit_time = Storage.getLocal('ARKFRISTPROFILE') || ''
23 | delete getPresetPropertiesLog.xcontext.$is_login
24 |
25 | var presetPropertiesLog = Util.delEmpty(getPresetPropertiesLog.xcontext)
26 | if (Util.paramType(callback) === 'Function') {
27 | callback.call(callback, presetPropertiesLog)
28 | }
29 | return presetPropertiesLog
30 | }
31 | export {
32 | getPresetProperties
33 | }
34 |
--------------------------------------------------------------------------------
/src/API/template/getSuperProperties.js:
--------------------------------------------------------------------------------
1 | import { resetCode } from '../../lib/fillField/index.js'
2 | import { successLog } from '../../lib/printLog/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import Storage from '../../lib/storage/index.js'
5 | import Util from '../../lib/common/index.js'
6 | import { transporter } from '../../lib/upload/hybrid.js'
7 | function getSuperProperties (callback) {
8 | baseConfig.status.FnName = '$getSuperProperties'
9 | resetCode()
10 | if (baseConfig.base.isHybrid === true) {
11 | var callbackFn = 'AnsCallback' + +new Date()
12 | window[callbackFn] = function () {
13 | callback.apply(callback, arguments)
14 | delete window[callbackFn]
15 | }
16 | transporter('getSuperProperties', [], callbackFn)
17 | return
18 | }
19 | var arkSuper = Storage.getLocal('ARKSUPER') || {}
20 | baseConfig.status.successCode = '20010'
21 | baseConfig.status.value = JSON.stringify(arkSuper)
22 | successLog()
23 | if (Util.paramType(callback) === 'Function') {
24 | callback.call(callback, arkSuper)
25 | }
26 | return arkSuper
27 | }
28 | export { getSuperProperties }
29 |
--------------------------------------------------------------------------------
/src/API/template/getSuperProperty.js:
--------------------------------------------------------------------------------
1 | import { checkPrivate, resetCode } from '../../lib/fillField/index.js'
2 | import { successLog } from '../../lib/printLog/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import Storage from '../../lib/storage/index.js'
5 | import Util from '../../lib/common/index.js'
6 | import { backParamsArray, transporter } from '../../lib/upload/hybrid.js'
7 | function getSuperProperty (superPropertyName, callback) {
8 | baseConfig.status.FnName = '$getSuperProperty'
9 | resetCode()
10 | if (baseConfig.base.isHybrid === true) {
11 | var paramArray = backParamsArray(superPropertyName)
12 | var callbackFn = 'AnsCallback' + +new Date()
13 | window[callbackFn] = function () {
14 | callback.apply(callback, arguments)
15 | delete window[callbackFn]
16 | }
17 | transporter('getSuperProperty', paramArray.argArray, callbackFn)
18 | return
19 | }
20 | checkPrivate(superPropertyName, '$getSuperProperty', true)
21 | // if (!status) {
22 | // return
23 | // }
24 | var arkSuper = Storage.getLocal('ARKSUPER') || {}
25 | var superProperty = arkSuper[superPropertyName]
26 |
27 | if (!{}.hasOwnProperty.call(arkSuper, superPropertyName)) {
28 | baseConfig.status.successCode = '20009'
29 | superProperty = ''
30 | } else {
31 | baseConfig.status.successCode = '20010'
32 | baseConfig.status.value = superProperty
33 | }
34 | baseConfig.status.key = superPropertyName
35 | successLog()
36 | if (Util.paramType(callback) === 'Function') {
37 | callback.call(callback, superProperty)
38 | }
39 | return superProperty
40 | }
41 | export { getSuperProperty }
42 |
--------------------------------------------------------------------------------
/src/API/template/identify.js:
--------------------------------------------------------------------------------
1 | import { checkPrivate, resetCode } from '../../lib/fillField/index.js'
2 | import { successLog } from '../../lib/printLog/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import Storage from '../../lib/storage/index.js'
5 | import Util from '../../lib/common/index.js'
6 | import { backParamsArray, transporter } from '../../lib/upload/hybrid.js'
7 | function identify (distinctId, isLogin, callback) {
8 | baseConfig.status.FnName = '$identify'
9 | resetCode()
10 | if (baseConfig.base.isHybrid === true) {
11 | var backParams = backParamsArray(distinctId, callback)
12 | var paramArray = backParams.argArray
13 | transporter('identify', paramArray, backParams.callback)
14 | return
15 | }
16 | var status = checkPrivate(distinctId, '$alias', true)
17 | if (!status) {
18 | return
19 | }
20 | if (Util.paramType(isLogin) === 'Boolean' && isLogin === true) {
21 | Storage.setLocal('ARK_TRACK_LOGIN', true)
22 | } else if (Util.paramType(isLogin) === 'Function') {
23 | callback = isLogin
24 | }
25 |
26 | Storage.setLocal('ARK_TRACKID', distinctId)
27 | Storage.setCookie('ARK_ID', distinctId)
28 | baseConfig.status.successCode = '20002'
29 | baseConfig.status.value = distinctId
30 | successLog()
31 | if (Util.paramType(callback) === 'Function') {
32 | callback.call(callback)
33 | }
34 | if (window.AnalysysModal && typeof (window.AnalysysModal) === 'function') {
35 | window.AnalysysModal([{ xwhat: '$identify', xwho: distinctId }])
36 | }
37 | }
38 | export { identify }
39 |
--------------------------------------------------------------------------------
/src/API/template/pageView.js:
--------------------------------------------------------------------------------
1 | import { temp } from '../../lib/mergeRules/index.js'
2 | import { fillField, checkPrivate, resetCode } from '../../lib/fillField/index.js'
3 | import { setReferrer } from '../../lib/fillField/getField.js'
4 | import baseConfig from '../../lib/baseConfig/index.js'
5 | import { upLog } from '../../lib/upload/index.js'
6 | import Util from '../../lib/common/index.js'
7 | import Storage from '../../lib/storage/index.js'
8 | import { transporter, backParamsArray } from '../../lib/upload/hybrid.js'
9 |
10 | var pageCloseStatus = false
11 | var pageUrl = window.location.href
12 |
13 | /**
14 | * @method pageView 统计页面事件
15 | * 第一个参数为页面名称 类型:String
16 | * 第二个参数为自定义属性 类型:Object/Function
17 | * 第三个参数为回调函数 类型:Function
18 | * 示例:
19 | * AnalysysAgent.pageView('首页')
20 | * AnalysysAgent.pageView('首页',{ 'commodityName': 'iPhone'})
21 | * AnalysysAgent.pageView('首页',{
22 | * 'commodityName': function(){
23 | * return 'iPhone'
24 | * }
25 | * })
26 | * AnalysysAgent.pageView('首页',{
27 | * 'commodityName': function(){
28 | * return 'iPhone'
29 | * }
30 | * },function(){
31 | * console.log('上报日志成功')
32 | * })
33 | * @param {String} pageName
34 | * @param {Object} obj
35 | * @param {function} callback
36 | */
37 | function pageView (pageName, obj, callback) {
38 | var log = pageViewLog(pageName, obj, callback)
39 |
40 | // 去除空数据后上传数据
41 | upLog(log, callback)
42 | }
43 |
44 | function pageViewLog (p, o, c) {
45 | var pageName = p
46 | var obj = o
47 | var callback = c
48 | // 页面关闭组件发送
49 | if (window.AnalysysModule && window.AnalysysModule.pageClose) {
50 | if (pageCloseStatus === true) {
51 | window.AnalysysModule.pageClose.pageEndTrack()
52 | } else {
53 | pageCloseStatus = true
54 | }
55 | if (Util.paramType(pageName) === 'String') {
56 | window.AnalysysModule.pageClose.createTime(+new Date(), pageName)
57 | } else {
58 | window.AnalysysModule.pageClose.createTime(+new Date())
59 | }
60 | }
61 |
62 | baseConfig.status.FnName = '$pageview'
63 | resetCode()
64 | var nameObj = {}
65 | if (Util.paramType(pageName) === 'String') {
66 | nameObj = {
67 | $title: pageName
68 | }
69 | checkPrivate(nameObj)
70 | } else if (Util.paramType(pageName) === 'Object') {
71 | if (Util.paramType(obj) === 'Function') {
72 | callback = obj
73 | }
74 | obj = pageName
75 | pageName = ''
76 | } else if (Util.paramType(pageName) === 'Function') {
77 | callback = pageName
78 | obj = ''
79 | pageName = ''
80 | }
81 | if (Util.paramType(obj) === 'Function') {
82 | callback = obj
83 | obj = ''
84 | }
85 | var userProp = {}
86 |
87 | if (Util.paramType(obj) === 'Object') {
88 | for (var key in obj) {
89 | if (Util.paramType(obj[key]) === 'Function') {
90 | obj[key] = obj[key].call(obj[key])
91 | }
92 | }
93 | // 检测用户自定义属性
94 | if (baseConfig.base.isHybrid === false) {
95 | checkPrivate(obj)
96 | }
97 | userProp = {
98 | xcontext: obj || {}
99 | }
100 | }
101 |
102 | var arkSuper = Storage.getLocal('ARKSUPER') || {}
103 | if (baseConfig.base.isHybrid === true) {
104 | arkSuper = {}
105 | }
106 | /**
107 | * 超级属性与用户自定义属性合并
108 | */
109 | var xcontext = Util.objMerge({
110 | xcontext: arkSuper
111 | }, userProp, {arrMerge: false})
112 | /**
113 | * 与$pagename属性合并
114 | */
115 | xcontext = Util.objMerge(xcontext, {
116 | xcontext: nameObj
117 | })
118 |
119 | var pageViewTemp = temp('$pageview')
120 | var pageViewObj = Util.delEmpty(fillField(pageViewTemp))
121 | if (baseConfig.base.isHybrid === true) {
122 | pageViewTemp = temp('$pageviewbase')
123 | pageViewObj = Util.delEmpty(fillField(pageViewTemp))
124 | var hybridPageViewLog = Util.objMerge(pageViewObj, xcontext)
125 | hybridPageViewLog = Util.delNotHybrid(Util.delEmpty(hybridPageViewLog.xcontext))
126 | var backParams = backParamsArray(pageName || '', hybridPageViewLog, callback)
127 | var paramArray = backParams.argArray
128 | transporter('pageView', paramArray, backParams.callback)
129 | setReferrer(pageUrl)
130 |
131 | return
132 | }
133 |
134 | setReferrer(pageUrl)
135 | /**
136 | * 自动采集与个性化属性合并
137 | */
138 | return Util.objMerge(pageViewObj, xcontext)
139 | }
140 |
141 |
142 | function hashPageView () {
143 | Util.changeHash(function () {
144 | if (pageUrl !== window.location.href) {
145 | pageUrl = window.location.href
146 | /**
147 | * 判断黑白名单
148 | * 符合黑名单,不上报
149 | * 有白名单,且不符合白名单,不上报
150 | */
151 | var listStatus = false
152 | if (baseConfig.base.pageViewWhiteList && Util.checkTypeList(baseConfig.base.pageViewWhiteList)) {
153 | listStatus = true
154 | } else if (!Util.checkTypeList(baseConfig.base.pageViewBlackList)) {
155 | listStatus = true
156 | }
157 | if (listStatus === true) {
158 | pageView()
159 | }
160 | }
161 | })
162 | }
163 | export { pageView, hashPageView, pageViewLog }
164 |
--------------------------------------------------------------------------------
/src/API/template/profileAppend.js:
--------------------------------------------------------------------------------
1 | import { temp } from '../../lib/mergeRules/index.js'
2 | import { fillField, checkPrivate, resetCode } from '../../lib/fillField/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import { upLog } from '../../lib/upload/index.js'
5 | import Util from '../../lib/common/index.js'
6 | import { backParamsArray, transporter } from '../../lib/upload/hybrid.js'
7 |
8 | function profileAppend (key, value, callback) {
9 | baseConfig.status.FnName = '$profile_append'
10 | resetCode()
11 |
12 | if (Util.paramType(key) === 'Object' && Util.paramType(value) === 'Function') {
13 | callback = value
14 | value = ''
15 | } else if (Util.paramType(key) === 'String' && Util.paramType(value) === 'Function') {
16 | value = value.call(value)
17 | }
18 | var obj = Util.toObj(key, value)
19 | for (var itemKey in obj) {
20 | if (Util.paramType(obj[itemKey]) === 'Function') {
21 | obj[itemKey] = obj[itemKey].call(obj[itemKey])
22 | }
23 | }
24 |
25 | if (baseConfig.base.isHybrid === true) {
26 | var backParams = backParamsArray(key, value, callback)
27 | var paramArray = backParams.argArray
28 | transporter('profileAppend', paramArray, backParams.callback)
29 | return
30 | }
31 | checkPrivate(obj, '$profile_append')
32 |
33 | var profileAppendTemp = temp('$profile_append')
34 |
35 | var profileAppendObj = Util.delEmpty(fillField(profileAppendTemp))
36 |
37 | var profileAppendLog = Util.objMerge(profileAppendObj, { xcontext: obj })
38 |
39 | // 如字段中有不合法内容则打印错误日志
40 | // if (!profileAppendLog) {
41 | // errorLog()
42 | // return
43 | // }
44 | // 去除空数据后上传数据
45 | upLog(profileAppendLog, callback)
46 | }
47 | export { profileAppend }
48 |
--------------------------------------------------------------------------------
/src/API/template/profileDelete.js:
--------------------------------------------------------------------------------
1 | import { temp } from '../../lib/mergeRules/index.js'
2 | import { fillField, resetCode } from '../../lib/fillField/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import { upLog } from '../../lib/upload/index.js'
5 | import { transporter } from '../../lib/upload/hybrid.js'
6 |
7 | function profileDelete (callback) {
8 | baseConfig.status.FnName = '$profile_delete'
9 | resetCode()
10 | if (baseConfig.base.isHybrid === true) {
11 | transporter('profileDelete', [], callback)
12 | return
13 | }
14 | var profileDeleteTemp = temp('$profile_delete')
15 |
16 | var profileDeleteLog = fillField(profileDeleteTemp)
17 |
18 | // 如字段中有不合法内容则打印错误日志
19 | // if (!profileDeleteLog) {
20 | // errorLog()
21 | // return
22 | // }
23 | // 去除空数据后上传数据
24 | upLog(profileDeleteLog, callback)
25 | }
26 | export { profileDelete }
27 |
--------------------------------------------------------------------------------
/src/API/template/profileIncrement.js:
--------------------------------------------------------------------------------
1 | import { temp } from '../../lib/mergeRules/index.js'
2 | import { fillField, checkPrivate, resetCode } from '../../lib/fillField/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import { upLog } from '../../lib/upload/index.js'
5 | import Util from '../../lib/common/index.js'
6 | import { backParamsArray, transporter } from '../../lib/upload/hybrid.js'
7 | function profileIncrement (key, value, callback) {
8 | baseConfig.status.FnName = '$profile_increment'
9 | resetCode()
10 |
11 | if (Util.paramType(key) === 'Object' && Util.paramType(value) === 'Function') {
12 | callback = value
13 | value = ''
14 | } else if (Util.paramType(key) === 'String' && Util.paramType(value) === 'Function') {
15 | value = value.call(value)
16 | }
17 | var obj = Util.toObj(key, value)
18 |
19 | for (var itemKey in obj) {
20 | if (Util.paramType(obj[itemKey]) === 'Function') {
21 | obj[itemKey] = obj[itemKey].call(obj[itemKey])
22 | }
23 | }
24 | if (baseConfig.base.isHybrid === true) {
25 | var backParams = backParamsArray(key, value, callback)
26 | var paramArray = backParams.argArray
27 | transporter('profileIncrement', paramArray, backParams.callback)
28 | return
29 | }
30 | checkPrivate(obj, '$profile_increment')
31 |
32 | var profileIncrementTemp = temp('$profile_increment')
33 |
34 | var profileIncrementObj = Util.delEmpty(fillField(profileIncrementTemp))
35 |
36 | var profileIncrementLog = Util.objMerge(profileIncrementObj, { xcontext: obj })
37 |
38 | // 如字段中有不合法内容则打印错误日志
39 | // if (!profileIncrementLog) {
40 | // errorLog()
41 | // return
42 | // }
43 | // 去除空数据后上传数据
44 | upLog(profileIncrementLog, callback)
45 | }
46 | export { profileIncrement }
47 |
--------------------------------------------------------------------------------
/src/API/template/profileSet.js:
--------------------------------------------------------------------------------
1 | import { temp } from '../../lib/mergeRules/index.js'
2 | import { fillField, checkPrivate, resetCode } from '../../lib/fillField/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import { upLog } from '../../lib/upload/index.js'
5 | import Util from '../../lib/common/index.js'
6 | import { backParamsArray, transporter } from '../../lib/upload/hybrid.js'
7 | function profileSet (key, value, callback) {
8 | baseConfig.status.FnName = '$profile_set'
9 | resetCode()
10 | if (Util.paramType(key) === 'Object' && Util.paramType(value) === 'Function') {
11 | callback = value
12 | value = ''
13 | } else if (Util.paramType(key) === 'String' && Util.paramType(value) === 'Function') {
14 | value = value.call(value)
15 | }
16 | var obj = Util.toObj(key, value)
17 |
18 | for (var itemKey in obj) {
19 | if (Util.paramType(obj[itemKey]) === 'Function') {
20 | obj[itemKey] = obj[itemKey].call(obj[itemKey])
21 | }
22 | }
23 | if (baseConfig.base.isHybrid === true) {
24 | var backParams = backParamsArray(key, value, callback)
25 | var paramArray = backParams.argArray
26 | transporter('profileSet', paramArray, backParams.callback)
27 | return
28 | }
29 | checkPrivate(obj, '$profile_set')
30 |
31 | var profileSetTemp = temp('$profile_set')
32 |
33 | var profileSetObj = Util.delEmpty(fillField(profileSetTemp))
34 |
35 | var profileSetLog = Util.objMerge(profileSetObj, { xcontext: obj })
36 |
37 | // 如字段中有不合法内容则打印错误日志
38 | // if (!profileSetLog) {
39 | // errorLog()
40 | // return
41 | // }
42 | // 去除空数据后上传数据
43 | upLog(profileSetLog, callback)
44 | }
45 | export { profileSet }
46 |
--------------------------------------------------------------------------------
/src/API/template/profileSetOnce.js:
--------------------------------------------------------------------------------
1 | import { temp } from '../../lib/mergeRules/index.js'
2 | import { fillField, checkPrivate, resetCode } from '../../lib/fillField/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import { upLog } from '../../lib/upload/index.js'
5 | import Util from '../../lib/common/index.js'
6 | import { backParamsArray, transporter } from '../../lib/upload/hybrid.js'
7 | function profileSetOnce (key, value, callback) {
8 | baseConfig.status.FnName = '$profile_set_once'
9 | resetCode()
10 | if (Util.paramType(key) === 'Object' && Util.paramType(value) === 'Function') {
11 | callback = value
12 | value = ''
13 | } else if (Util.paramType(key) === 'String' && Util.paramType(value) === 'Function') {
14 | value = value.call(value)
15 | }
16 | var obj = Util.toObj(key, value)
17 |
18 | for (var itemKey in obj) {
19 | if (Util.paramType(obj[itemKey]) === 'Function') {
20 | obj[itemKey] = obj[itemKey].call(obj[itemKey])
21 | }
22 | }
23 | if (baseConfig.base.isHybrid === true) {
24 | var backParams = backParamsArray(obj, callback)
25 | var paramArray = backParams.argArray
26 | transporter('profileSetOnce', paramArray, backParams.callback)
27 | return
28 | }
29 | checkPrivate(obj, '$profile_set_once')
30 |
31 | var profileSetOnceTemp = temp('$profile_set_once')
32 |
33 | var profileSetOnceObj = Util.delEmpty(fillField(profileSetOnceTemp))
34 |
35 | var profileSetOnceLog = Util.objMerge(profileSetOnceObj, { xcontext: obj })
36 |
37 | // 如字段中有不合法内容则打印错误日志
38 | // if (!profileSetOnceLog) {
39 | // errorLog()
40 | // return
41 | // }
42 | // 去除空数据后上传数据
43 | upLog(profileSetOnceLog, callback)
44 | }
45 | export { profileSetOnce }
46 |
--------------------------------------------------------------------------------
/src/API/template/profileUnset.js:
--------------------------------------------------------------------------------
1 | import { temp } from '../../lib/mergeRules/index.js'
2 | import { fillField, checkPrivate, resetCode } from '../../lib/fillField/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import { upLog } from '../../lib/upload/index.js'
5 | import Util from '../../lib/common/index.js'
6 | import { backParamsArray, transporter } from '../../lib/upload/hybrid.js'
7 | function profileUnset (key, callback) {
8 | baseConfig.status.FnName = '$profile_unset'
9 | resetCode()
10 | if (Util.paramType(key) === 'Function') {
11 | key = key.call(key)
12 | }
13 | checkPrivate(key, '$profile_unset', key)
14 | var obj = Util.toObj(key, '')
15 | if (baseConfig.base.isHybrid === true) {
16 | var backParams = backParamsArray(key, callback)
17 | var paramArray = backParams.argArray
18 | transporter('profileUnset', paramArray, backParams.callback)
19 | return
20 | }
21 | checkPrivate(obj, '$profile_unset')
22 |
23 | var profileUnsetTemp = temp('$profile_unset')
24 |
25 | var profileUnsetObj = fillField(profileUnsetTemp)
26 |
27 | var profileUnsetLog = Util.objMerge(profileUnsetObj, { xcontext: obj })
28 |
29 | // 如字段中有不合法内容则打印错误日志
30 | // if (!profileUnsetLog) {
31 | // errorLog()
32 | // return
33 | // }
34 | // 去除空数据后上传数据
35 | upLog(profileUnsetLog, callback)
36 | }
37 | export { profileUnset }
38 |
--------------------------------------------------------------------------------
/src/API/template/registerSuperProperties.js:
--------------------------------------------------------------------------------
1 | import { checkPrivate, resetCode } from '../../lib/fillField/index.js'
2 | import { successLog } from '../../lib/printLog/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import Util from '../../lib/common/index.js'
5 | import Storage from '../../lib/storage/index.js'
6 | import { backParamsArray, transporter } from '../../lib/upload/hybrid.js'
7 | function registerSuperProperties (key, value, callback) {
8 | baseConfig.status.FnName = '$registerSuperProperties'
9 | resetCode()
10 | if (Util.paramType(key) === 'Object' && Util.paramType(value) === 'Function') {
11 | callback = value
12 | value = ''
13 | } else if (Util.paramType(key) === 'String' && Util.paramType(value) === 'Function') {
14 | value = value.call(value)
15 | }
16 | var obj = Util.toObj(key, value)
17 | for (var itemKey in obj) {
18 | if (Util.paramType(obj[itemKey]) === 'Function') {
19 | obj[itemKey] = obj[itemKey].call(obj[itemKey])
20 | }
21 | }
22 | if (baseConfig.base.isHybrid === true) {
23 | var backParams = backParamsArray(key, value, callback)
24 | var paramArray = backParams.argArray
25 | transporter('registerSuperProperties', paramArray, backParams.callback)
26 | return
27 | }
28 | checkPrivate(obj, '$registerSuperProperties')
29 |
30 | var arkSuper = Storage.getLocal('ARKSUPER') || {}
31 | // obj = Util.delEmpty(obj)
32 | var saveArkSuper = Util.objMerge(arkSuper, obj, {
33 | arrMerge: false
34 | })
35 | Storage.setLocal('ARKSUPER', saveArkSuper)
36 |
37 | baseConfig.status.successCode = '20002'
38 | baseConfig.status.value = JSON.stringify(obj)
39 | successLog()
40 | Util.paramType(callback) === 'Function' && callback.call(callback)
41 | }
42 | export { registerSuperProperties }
43 |
--------------------------------------------------------------------------------
/src/API/template/registerSuperProperty.js:
--------------------------------------------------------------------------------
1 | import { checkPrivate, resetCode } from '../../lib/fillField/index.js'
2 | import { successLog } from '../../lib/printLog/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import Util from '../../lib/common/index.js'
5 | import Storage from '../../lib/storage/index.js'
6 | import { backParamsArray, transporter } from '../../lib/upload/hybrid.js'
7 | function registerSuperProperty (key, value, callback) {
8 | baseConfig.status.FnName = '$registerSuperProperty'
9 | resetCode()
10 | if (Util.paramType(key) === 'Object' && Util.paramType(value) === 'Function') {
11 | callback = value
12 | value = ''
13 | } else if (Util.paramType(key) === 'String' && Util.paramType(value) === 'Function') {
14 | value = value.call(value)
15 | }
16 | var obj = Util.toObj(key, value)
17 | for (var itemKey in obj) {
18 | if (Util.paramType(obj[itemKey]) === 'Function') {
19 | obj[itemKey] = obj[itemKey].call(obj[itemKey])
20 | }
21 | }
22 | if (baseConfig.base.isHybrid === true) {
23 | var backParams = backParamsArray(key, value, callback)
24 | var paramArray = backParams.argArray
25 | transporter('registerSuperProperty', paramArray, backParams.callback)
26 | return
27 | }
28 | checkPrivate(obj, '$registerSuperProperty')
29 | // obj = Util.delEmpty(obj)
30 | var arkSuper = Storage.getLocal('ARKSUPER') || {}
31 | var saveArkSuper = Util.objMerge(arkSuper, obj, {
32 | arrMerge: false
33 | })
34 | Storage.setLocal('ARKSUPER', saveArkSuper)
35 | baseConfig.status.successCode = '20002'
36 | baseConfig.status.value = JSON.stringify(obj)
37 | successLog()
38 | Util.paramType(callback) === 'Function' && callback.call(callback)
39 | }
40 | export { registerSuperProperty }
41 |
--------------------------------------------------------------------------------
/src/API/template/reset.js:
--------------------------------------------------------------------------------
1 | import sessionId from '../../lib/fillField/sessionId.js'
2 | import { clearSuperProperties } from './clearSuperProperties.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import { successLog } from '../../lib/printLog/index.js'
5 | import Util from '../../lib/common/index.js'
6 | import { resetCode, clearCache } from '../../lib/fillField/index.js'
7 | import { removeUUId } from '../../lib/fillField/id.js'
8 | import { profileSetOnce } from './profileSetOnce.js'
9 | import { transporter } from '../../lib/upload/hybrid.js'
10 | function reset (callback) {
11 | if (baseConfig.base.isHybrid === true) {
12 | transporter('reset', [], callback)
13 | return
14 | }
15 | resetCode()
16 | removeUUId()
17 | clearSuperProperties()
18 | clearCache(true)
19 | sessionId.setId()
20 | if (baseConfig.base.autoProfile === true) {
21 | var resetTime = {
22 | $reset_time: Util.format(new Date(), 'yyyy-MM-dd hh:mm:ss.SSS')
23 | }
24 | profileSetOnce(resetTime, callback)
25 | } else {
26 | if (Util.paramType(callback) === 'Function') {
27 | callback.call(callback)
28 | }
29 | }
30 | baseConfig.status.FnName = '$reset'
31 | baseConfig.status.successCode = '20005'
32 | successLog()
33 | }
34 | export { reset }
35 |
--------------------------------------------------------------------------------
/src/API/template/startUp.js:
--------------------------------------------------------------------------------
1 | import { temp } from '../../lib/mergeRules/index.js'
2 | import { fillField, isStartUp, checkBase } from '../../lib/fillField/index.js'
3 | import { errorLog } from '../../lib/printLog/index.js'
4 | import baseConfig from '../../lib/baseConfig/index.js'
5 | import { upLog } from '../../lib/upload/index.js'
6 | import Util from '../../lib/common/index.js'
7 | import { hashPageView } from './pageView.js'
8 | import Storage from '../../lib/storage/index.js'
9 | import { pageViewLog } from './pageView.js'
10 |
11 | function startUp () {
12 | var log = []
13 | // 启动前检测appkey、debugModel、uploadURL参数是否合法
14 | if (baseConfig.base.isHybrid === false && !checkBase()) {
15 | errorLog()
16 | return
17 | }
18 | var arkSuper = Storage.getLocal('ARKSUPER') || {}
19 | // 检测启动前状态,appid,debugModel,uploadURL是否存在修改
20 | // 判断是否是已启动
21 | // 如已启动则不发送启动日志
22 | if (baseConfig.base.isHybrid === false && isStartUp() === false) {
23 | var startUpStatus = true
24 | if (Util.checkTypeList(baseConfig.base.startUpBlackList) || (baseConfig.base.startUpWhiteList && !Util.checkTypeList(baseConfig.base.startUpWhiteList))) {
25 | startUpStatus = false
26 | }
27 | if (startUpStatus === true) {
28 | baseConfig.status.FnName = '$startup'
29 | // 更新当前所在事件
30 | // baseConfig.status.FnName = '$startup'
31 |
32 | // 获取事件日志模板
33 | var startUpTemp = temp('$startup')
34 | // 验证及填充日志模板中字段内容
35 | // 如未通过验证则返回值为fasle
36 | var startUpLog = fillField(startUpTemp)
37 |
38 | /**
39 | * 超级属性优先于自动采集属性
40 | */
41 | startUpLog = Util.objMerge(startUpLog, {
42 | xcontext: arkSuper
43 | }, {arrMerge: false})
44 | log.push(Util.delEmpty(startUpLog))
45 | }
46 | }
47 |
48 | // 自动采集首次用户属性
49 | var fristProfile = Storage.getLocal('ARKFRISTPROFILE') || false
50 | if (baseConfig.base.isHybrid === false && baseConfig.base.autoProfile === true && !fristProfile) {
51 | baseConfig.status.FnName = '$profile_set_once'
52 | var profileSetOnceTemp = temp('$profile_set_once')
53 |
54 | var profileSetOnceObj = fillField(profileSetOnceTemp)
55 | var time = Storage.getLocal('ARKFRISTPROFILE') || Util.format(new Date(), 'yyyy-MM-dd hh:mm:ss.SSS')
56 | var obj = {
57 | $first_visit_time: time,
58 | $first_visit_language: (navigator.language || navigator.browserLanguage).toLowerCase()
59 | }
60 | /**
61 | * 自定义属性优先于自动采集属性
62 | */
63 | var profileSetOnceLog = Util.objMerge(profileSetOnceObj, {
64 | xcontext: obj
65 | })
66 | log.push(Util.delEmpty(profileSetOnceLog))
67 | Storage.setLocal('ARKFRISTPROFILE', time)
68 | }
69 |
70 | // 自动采集页面
71 | if (baseConfig.base.auto === true) {
72 | /**
73 | * 判断黑白名单
74 | * 符合黑名单,不上报
75 | * 有白名单,且不符合白名单,不上报
76 | */
77 | var listStatus = false
78 | if (baseConfig.base.pageViewWhiteList && Util.checkTypeList(baseConfig.base.pageViewWhiteList)) {
79 | listStatus = true
80 | } else if (!Util.checkTypeList(baseConfig.base.pageViewBlackList)) {
81 | listStatus = true
82 | }
83 | if (listStatus === true) {
84 | var pageLog = pageViewLog(baseConfig.base.pageProperty)
85 |
86 | log.push(pageLog)
87 | }
88 | // 开启hash跳转
89 | if (baseConfig.base.hash === true || baseConfig.base.singlePage === true) {
90 | hashPageView()
91 | }
92 | }
93 | if (log.length > 0) {
94 | upLog(log)
95 | }
96 | // 校准时间
97 | }
98 | export { startUp }
99 |
--------------------------------------------------------------------------------
/src/API/template/track.js:
--------------------------------------------------------------------------------
1 | import { temp } from '../../lib/mergeRules/index.js'
2 | import { fillField, checkPrivate, resetCode } from '../../lib/fillField/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import { upLog } from '../../lib/upload/index.js'
5 | import Util from '../../lib/common/index.js'
6 | import Storage from '../../lib/storage/index.js'
7 | import { transporter, backParamsArray } from '../../lib/upload/hybrid.js'
8 | function track (eventName, obj, callback) {
9 | baseConfig.status.FnName = eventName || '$track'
10 | resetCode()
11 | checkPrivate(eventName, '$track', true)
12 | baseConfig.status.FnName = eventName
13 | var userProp = {}
14 | if (Util.paramType(obj) === 'Function') {
15 | callback = obj
16 | obj = {}
17 | }
18 | if (Util.paramType(obj) === 'Object') {
19 | for (var itemKey in obj) {
20 | if (Util.paramType(obj[itemKey]) === 'Function') {
21 | obj[itemKey] = obj[itemKey].call(obj[itemKey])
22 | }
23 | }
24 | checkPrivate(obj)
25 | userProp = {
26 | xcontext: obj
27 | }
28 | }
29 | var arkSuper = Storage.getLocal('ARKSUPER') || {}
30 |
31 | /**
32 | * 用户自定义属性优先于超级属性
33 | */
34 |
35 | var xcontext = Util.objMerge({
36 | xcontext: arkSuper
37 | }, userProp, {arrMerge: false})
38 | if (baseConfig.base.isHybrid === true) {
39 | var trackHybridTemp = temp('$trackbase')
40 | var trackHybridObj = fillField(trackHybridTemp)
41 | trackHybridObj = Util.delEmpty(trackHybridObj)
42 | var hybridPageViewLog = Util.objMerge(trackHybridObj, xcontext)
43 | hybridPageViewLog = Util.delNotHybrid(Util.delEmpty(hybridPageViewLog.xcontext))
44 | var backParams = backParamsArray(eventName, hybridPageViewLog, callback)
45 | var paramArray = backParams.argArray
46 | // paramArray.postion = elePostionObj || null
47 | transporter('track', paramArray, backParams.callback)
48 | // window.AnalysysAgentHybrid.track(eventName, JSON.stringify(userProp.xcontext), JSON.stringify(elePostionObj))
49 | return
50 | }
51 |
52 | var trackTemp = temp('$track')
53 | var trackObj = fillField(trackTemp)
54 | /**
55 | * 去空逻辑,不对xwhat进行去空
56 | */
57 | trackObj.xcontext = Util.delEmpty(trackObj.xcontext)
58 | /**
59 | * 自定义属性优先于自动采集属性
60 | */
61 | var trackLog = Util.objMerge(trackObj, xcontext, {arrMerge: false})
62 |
63 | // 去除空数据后上传数据
64 | upLog(trackLog, callback)
65 | }
66 | export { track }
67 |
--------------------------------------------------------------------------------
/src/API/template/unRegisterSuperProperty.js:
--------------------------------------------------------------------------------
1 | import { checkPrivate, resetCode } from '../../lib/fillField/index.js'
2 | import { successLog } from '../../lib/printLog/index.js'
3 | import baseConfig from '../../lib/baseConfig/index.js'
4 | import Storage from '../../lib/storage/index.js'
5 | import Util from '../../lib/common/index.js'
6 | import { backParamsArray, transporter } from '../../lib/upload/hybrid.js'
7 | function unRegisterSuperProperty (superPropertyName, callback) {
8 | baseConfig.status.FnName = '$unregisterSuperProperty'
9 | resetCode()
10 | if (baseConfig.base.isHybrid === true) {
11 | var backParams = backParamsArray.apply(superPropertyName, arguments)
12 | var paramArray = backParams.argArray
13 | transporter('unRegisterSuperProperty', paramArray, backParams.callback)
14 | return
15 | }
16 | checkPrivate(superPropertyName, '$unregisterSuperProperty', true)
17 | var arkSuper = Storage.getLocal('ARKSUPER') || {}
18 | if (!Object.prototype.hasOwnProperty.call(arkSuper, superPropertyName)) {
19 | baseConfig.status.successCode = '20011'
20 | } else {
21 | delete arkSuper[superPropertyName]
22 | Storage.setLocal('ARKSUPER', arkSuper)
23 | baseConfig.status.successCode = '20003'
24 | }
25 | baseConfig.status.value = superPropertyName
26 | successLog()
27 | Util.paramType(callback) === 'Function' && callback.call(callback)
28 | }
29 | export { unRegisterSuperProperty }
30 |
--------------------------------------------------------------------------------
/src/configure/base/fieldRules.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 字段填充、字段校验规则模板
3 | *
4 | * ReservedKeywords:不可覆盖字段集合
5 | *
6 | * valueType:获取字段值的方式 0:函数获取 1:默认值
7 | *
8 | * value:根据valueType规则填充字段对应取值
9 | *
10 | * checkList:数据合法检测方法列表,每个方法返回bool值,以用户为准,同名覆盖
11 | *
12 | */
13 | import {
14 | getAppId,
15 | getUploadURL,
16 | getId,
17 | nowDate,
18 | getXwhat,
19 | getDebugMode,
20 | isLogin,
21 | getLibVersion,
22 | timeZone,
23 | language,
24 | getSessionId,
25 | isFirstTime,
26 | isFirstDay,
27 | originalId,
28 | getReferrer,
29 | getReferrerDomain,
30 | getTitle,
31 | getUrl,
32 | getScreenWidth,
33 | getScreenHeight,
34 | startupTime,
35 | checkSpider,
36 | utmCampaignId,
37 | utmSource,
38 | utmMedium,
39 | utmTerm,
40 | utmContent,
41 | utmCampaign,
42 | timeCalibration
43 | } from '../../lib/fillField/getField.js'
44 |
45 | export default {
46 | resetKeywords: [
47 | 'appid',
48 | '$debug',
49 | 'uploadUrl'
50 | ],
51 | uploadURL: {
52 | valueType: 0,
53 | value: getUploadURL,
54 | check: {
55 | value: ['isString', 'nimLength', 'isUrl'],
56 | errorCode: '60007',
57 | successCode: '20008'
58 | }
59 | },
60 | appid: {
61 | valueType: 0,
62 | value: getAppId,
63 | check: {
64 | value: ['isString', 'nimLength'],
65 | errorCode: '60006',
66 | successCode: '20006'
67 | }
68 | },
69 | hash: {
70 | check: {
71 | value: ['isBoolean'],
72 | errorCode: '60003'
73 | }
74 | },
75 | auto: {
76 | check: {
77 | value: ['isBoolean'],
78 | errorCode: '60003'
79 | }
80 | },
81 | autoProfile: {
82 | check: {
83 | value: ['isBoolean'],
84 | errorCode: '60003'
85 | }
86 | },
87 | pageProperty: {
88 | check: {
89 | value: ['isObject'],
90 | errorCode: '600016'
91 | }
92 | },
93 | xwho: {
94 | valueType: 0,
95 | value: getId,
96 | check: {
97 | value: ['isString', 'nimLength']
98 | }
99 | },
100 | xwhen: {
101 | valueType: 0,
102 | value: nowDate
103 | },
104 |
105 | xwhat: {
106 | valueType: 0,
107 | value: getXwhat,
108 | check: {
109 | value: ['isString', 'nimLength']
110 | }
111 | },
112 |
113 | xcontext: {
114 | $lib: {
115 | valueType: 1,
116 | value: 'JS'
117 | },
118 | $lib_version: {
119 | valueType: 0,
120 | value: getLibVersion,
121 | check: {
122 | value: ['isString'],
123 | successCode: '20007'
124 | }
125 | },
126 | $platform: {
127 | valueType: 1,
128 | value: 'JS'
129 | },
130 | $debug: {
131 | valueType: 0,
132 | value: getDebugMode,
133 | check: {
134 | value: ['isNumber', 'isDebug']
135 | }
136 | },
137 | $is_login: {
138 | valueType: 0,
139 | value: isLogin,
140 | check: {
141 | value: ['isBoolean']
142 | }
143 | },
144 | $screen_width: {
145 | valueType: 0,
146 | value: getScreenWidth,
147 | check: {
148 | value: ['isNumber']
149 | }
150 | },
151 | $screen_height: {
152 | valueType: 0,
153 | value: getScreenHeight,
154 | check: {
155 | value: ['isNumber']
156 | }
157 | },
158 |
159 | $time_zone: {
160 | valueType: 1,
161 | value: timeZone
162 | },
163 | $language: {
164 | valueType: 1,
165 | value: language
166 | },
167 | $session_id: {
168 | valueType: 0,
169 | value: getSessionId
170 | },
171 | $is_first_time: {
172 | valueType: 0,
173 | value: isFirstTime
174 | },
175 | $is_first_day: {
176 | valueType: 0,
177 | value: isFirstDay
178 | },
179 | $referrer: {
180 | valueType: 0,
181 | value: getReferrer
182 | },
183 | $referrer_domain: {
184 | valueType: 0,
185 | value: getReferrerDomain
186 | },
187 | $title: {
188 | valueType: 0,
189 | value: getTitle
190 | },
191 | $url: {
192 | valueType: 0,
193 | value: getUrl
194 | },
195 | $startup_time: {
196 | valueType: 0,
197 | value: startupTime
198 | },
199 | $web_crawler: {
200 | valueType: 0,
201 | value: checkSpider
202 | },
203 |
204 | $original_id: {
205 | valueType: 0,
206 | value: originalId
207 | },
208 | $utm_campaign_id: {
209 | valueType: 0,
210 | value: utmCampaignId
211 | },
212 | $utm_source: {
213 | valueType: 0,
214 | value: utmSource
215 | },
216 | $utm_medium: {
217 | valueType: 0,
218 | value: utmMedium
219 | },
220 | $utm_term: {
221 | valueType: 0,
222 | value: utmTerm
223 | },
224 | $utm_content: {
225 | valueType: 0,
226 | value: utmContent
227 | },
228 | $utm_campaign: {
229 | valueType: 0,
230 | value: utmCampaign
231 | },
232 | $is_time_calibrated: {
233 | valueType: 0,
234 | value: timeCalibration
235 | }
236 |
237 | },
238 |
239 | xcontextCommonRule: {
240 | check: {
241 | key: ['isString', 'length99', 'notSpecialCharacters', 'keywords'],
242 | value: ['notObject', 'isArrayString', 'length255']
243 | }
244 | },
245 | $track: {
246 | check: {
247 | key: ['isString', 'notSpecialCharacters', 'length99']
248 | }
249 | },
250 | $alias: {
251 | check: {
252 | key: ['isString', 'keyLength255']
253 | }
254 | },
255 | $profile_increment: {
256 | check: {
257 | key: ['isString', 'length99', 'notSpecialCharacters'],
258 | value: ['isNumber']
259 | }
260 | },
261 | $profile_unset: {
262 | check: {
263 | key: ['isString', 'length99', 'notSpecialCharacters']
264 | }
265 | },
266 | $pageview: {
267 | check: {
268 | key: ['isString', 'keyLength255']
269 | }
270 | }
271 | }
272 |
--------------------------------------------------------------------------------
/src/configure/base/fieldTemplate.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SDK 基础字段定义表
3 | * base.outer:上报日志基础结构定义
4 | * base.xcontext:上报报文找中xcontext下的共有字段定义
5 | * $开头的字段为各个事件特殊拥有字段
6 | */
7 | export default {
8 | base: {
9 | outer: [
10 | 'appid',
11 | 'xwho',
12 | 'xwhat',
13 | 'xwhen',
14 | 'xcontext'
15 | ],
16 | xcontext: [
17 | '$lib',
18 | '$lib_version',
19 | '$platform',
20 | '$debug',
21 | '$is_login'
22 | ]
23 | },
24 | $startup: {
25 | xcontext: [
26 | '$screen_width',
27 | '$screen_height',
28 | '$web_crawler',
29 | '$time_zone',
30 | '$language',
31 | '$session_id',
32 | '$is_first_time',
33 | '$is_first_day',
34 | '$utm_campaign_id',
35 | '$utm_source',
36 | '$utm_medium',
37 | '$utm_term',
38 | '$utm_content',
39 | '$utm_campaign',
40 | '$is_time_calibrated'
41 | ]
42 | },
43 | $track: {
44 | xcontext: [
45 | '$screen_width',
46 | '$screen_height',
47 | '$web_crawler',
48 | '$time_zone',
49 | '$language',
50 | '$is_first_day',
51 | '$session_id',
52 | '$utm_campaign_id',
53 | '$utm_source',
54 | '$utm_medium',
55 | '$utm_term',
56 | '$utm_content',
57 | '$utm_campaign',
58 | '$is_time_calibrated'
59 | ]
60 | },
61 | $pageview: {
62 | xcontext: [
63 | '$screen_width',
64 | '$screen_height',
65 | '$web_crawler',
66 | '$time_zone',
67 | '$language',
68 | '$session_id',
69 | '$is_first_day',
70 | '$referrer',
71 | '$referrer_domain',
72 | '$title',
73 | '$url',
74 | '$startup_time',
75 | '$utm_campaign_id',
76 | '$utm_source',
77 | '$utm_medium',
78 | '$utm_term',
79 | '$utm_content',
80 | '$utm_campaign',
81 | '$is_time_calibrated'
82 | ]
83 | },
84 | $alias: {
85 | xcontext: [
86 | '$original_id'
87 | ]
88 | },
89 | $getPresetProperties: {
90 | xcontext: [
91 | '$screen_width',
92 | '$screen_height',
93 | '$time_zone',
94 | '$session_id',
95 | '$language'
96 | ]
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/configure/base/index.js:
--------------------------------------------------------------------------------
1 | import fieldRules from './fieldRules.js'
2 | import fieldTemplate from './fieldTemplate.js'
3 | import lifecycle from './lifecycle.js'
4 |
5 | export {
6 | fieldRules,
7 | fieldTemplate,
8 | lifecycle
9 | }
10 |
--------------------------------------------------------------------------------
/src/configure/base/lifecycle.js:
--------------------------------------------------------------------------------
1 |
2 | export default {
3 | }
4 |
--------------------------------------------------------------------------------
/src/configure/customized/UA/configure/fieldRules.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 字段填充、字段校验规则模板
3 | *
4 | * check:数据合法检测方法列表,每个方法返回bool值,以用户为准,同名覆盖
5 | *
6 | */
7 | export default {
8 | xcontext: {
9 | $user_agent: {
10 | valueType: 1,
11 | value: window.navigator.userAgent.replace(/"/g, '\\"')
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/configure/customized/UA/configure/fieldTemplate.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SDK 基础字段定义表
3 | * base.outer:上报日志基础结构定义
4 | * base.xcontext:上报报文找中xcontext下的共有字段定义
5 | * $开头的字段为各个事件特殊拥有字段
6 | */
7 | var temp = {}
8 | var event = ['$startup', '$track', '$pageview', '$webstay', '$web_click', '$user_click']
9 | var common = {
10 | // "base": {
11 | xcontext: [
12 | '$user_agent'
13 | ]
14 | // }
15 | }
16 | for (var i = 0; i < event.length; i++) {
17 | temp[event[i]] = common
18 | }
19 | export default temp
20 |
--------------------------------------------------------------------------------
/src/configure/customized/UA/index.js:
--------------------------------------------------------------------------------
1 | import fieldRules from './configure/fieldRules.js'
2 | import fieldTemplate from './configure/fieldTemplate.js'
3 | export {
4 | fieldRules,
5 | fieldTemplate
6 | }
7 |
--------------------------------------------------------------------------------
/src/configure/customized/decodeGBK/configure/lifecycle.js:
--------------------------------------------------------------------------------
1 | import {
2 | decodeGBK
3 | } from '../lib/decodeGBK'
4 | export default {
5 | ParseStr: {
6 | gbkDecode: decodeGBK
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/configure/customized/decodeGBK/index.js:
--------------------------------------------------------------------------------
1 | import lifecycle from './configure/lifecycle.js'
2 | export {
3 | lifecycle
4 | }
5 |
--------------------------------------------------------------------------------
/src/configure/customized/encrypt/configure/fieldRules.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 字段填充、字段校验规则模板
3 | *
4 | * check:数据合法检测方法列表,每个方法返回bool值,以用户为准,同名覆盖
5 | *
6 | */
7 | export default {
8 | encryptType: {
9 | check: {
10 | value: ['isNumber']
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/configure/customized/encrypt/configure/fieldTemplate.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SDK 基础字段定义表
3 | * base.outer:上报日志基础结构定义
4 | * base.xcontext:上报报文找中xcontext下的共有字段定义
5 | * $开头的字段为各个事件特殊拥有字段
6 | */
7 | export default {
8 | }
9 |
--------------------------------------------------------------------------------
/src/configure/customized/encrypt/configure/lifecycle.js:
--------------------------------------------------------------------------------
1 | import { encryptInit, uploadData } from '../lib/encrypt.js'
2 | export default {
3 | AnalysysAgent: {
4 | init: encryptInit
5 | },
6 | upload: {
7 | init: uploadData
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/configure/customized/encrypt/index.js:
--------------------------------------------------------------------------------
1 | import fieldRules from './configure/fieldRules.js'
2 | import fieldTemplate from './configure/fieldTemplate.js'
3 | import lifecycle from './configure/lifecycle.js'
4 | export {
5 | fieldRules,
6 | fieldTemplate,
7 | lifecycle
8 | }
9 |
--------------------------------------------------------------------------------
/src/configure/customized/encrypt/lib/base64js.min.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | exports.byteLength = byteLength
4 | exports.toByteArray = toByteArray
5 | exports.fromByteArray = fromByteArray
6 |
7 | var lookup = []
8 | var revLookup = []
9 | var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
10 |
11 | var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
12 | for (var i = 0, len = code.length; i < len; ++i) {
13 | lookup[i] = code[i]
14 | revLookup[code.charCodeAt(i)] = i
15 | }
16 |
17 | // Support decoding URL-safe base64 strings, as Node.js does.
18 | // See: https://en.wikipedia.org/wiki/Base64#URL_applications
19 | revLookup['-'.charCodeAt(0)] = 62
20 | revLookup['_'.charCodeAt(0)] = 63
21 |
22 | function getLens (b64) {
23 | var len = b64.length
24 |
25 | if (len % 4 > 0) {
26 | throw new Error('Invalid string. Length must be a multiple of 4')
27 | }
28 |
29 | // Trim off extra bytes after placeholder bytes are found
30 | // See: https://github.com/beatgammit/base64-js/issues/42
31 | var validLen = b64.indexOf('=')
32 | if (validLen === -1) validLen = len
33 |
34 | var placeHoldersLen = validLen === len
35 | ? 0
36 | : 4 - (validLen % 4)
37 |
38 | return [validLen, placeHoldersLen]
39 | }
40 |
41 | // base64 is 4/3 + up to two characters of the original data
42 | function byteLength (b64) {
43 | var lens = getLens(b64)
44 | var validLen = lens[0]
45 | var placeHoldersLen = lens[1]
46 | return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
47 | }
48 |
49 | function _byteLength (b64, validLen, placeHoldersLen) {
50 | return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
51 | }
52 |
53 | function toByteArray (b64) {
54 | var tmp
55 | var lens = getLens(b64)
56 | var validLen = lens[0]
57 | var placeHoldersLen = lens[1]
58 |
59 | var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
60 |
61 | var curByte = 0
62 |
63 | // if there are placeholders, only get up to the last complete 4 chars
64 | var len = placeHoldersLen > 0
65 | ? validLen - 4
66 | : validLen
67 |
68 | var i
69 | for (i = 0; i < len; i += 4) {
70 | tmp =
71 | (revLookup[b64.charCodeAt(i)] << 18) |
72 | (revLookup[b64.charCodeAt(i + 1)] << 12) |
73 | (revLookup[b64.charCodeAt(i + 2)] << 6) |
74 | revLookup[b64.charCodeAt(i + 3)]
75 | arr[curByte++] = (tmp >> 16) & 0xFF
76 | arr[curByte++] = (tmp >> 8) & 0xFF
77 | arr[curByte++] = tmp & 0xFF
78 | }
79 |
80 | if (placeHoldersLen === 2) {
81 | tmp =
82 | (revLookup[b64.charCodeAt(i)] << 2) |
83 | (revLookup[b64.charCodeAt(i + 1)] >> 4)
84 | arr[curByte++] = tmp & 0xFF
85 | }
86 |
87 | if (placeHoldersLen === 1) {
88 | tmp =
89 | (revLookup[b64.charCodeAt(i)] << 10) |
90 | (revLookup[b64.charCodeAt(i + 1)] << 4) |
91 | (revLookup[b64.charCodeAt(i + 2)] >> 2)
92 | arr[curByte++] = (tmp >> 8) & 0xFF
93 | arr[curByte++] = tmp & 0xFF
94 | }
95 |
96 | return arr
97 | }
98 |
99 | function tripletToBase64 (num) {
100 | return lookup[num >> 18 & 0x3F] +
101 | lookup[num >> 12 & 0x3F] +
102 | lookup[num >> 6 & 0x3F] +
103 | lookup[num & 0x3F]
104 | }
105 |
106 | function encodeChunk (uint8, start, end) {
107 | var tmp
108 | var output = []
109 | for (var i = start; i < end; i += 3) {
110 | tmp =
111 | ((uint8[i] << 16) & 0xFF0000) +
112 | ((uint8[i + 1] << 8) & 0xFF00) +
113 | (uint8[i + 2] & 0xFF)
114 | output.push(tripletToBase64(tmp))
115 | }
116 | return output.join('')
117 | }
118 |
119 | function fromByteArray (uint8) {
120 | var tmp
121 | var len = uint8.length
122 | var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
123 | var parts = []
124 | var maxChunkLength = 16383 // must be multiple of 3
125 |
126 | // go through the array every three bytes, we'll deal with trailing stuff later
127 | for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
128 | parts.push(encodeChunk(
129 | uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)
130 | ))
131 | }
132 |
133 | // pad the end with zeros, but make sure to not forget the extra bytes
134 | if (extraBytes === 1) {
135 | tmp = uint8[len - 1]
136 | parts.push(
137 | lookup[tmp >> 2] +
138 | lookup[(tmp << 4) & 0x3F] +
139 | '=='
140 | )
141 | } else if (extraBytes === 2) {
142 | tmp = (uint8[len - 2] << 8) + uint8[len - 1]
143 | parts.push(
144 | lookup[tmp >> 10] +
145 | lookup[(tmp >> 4) & 0x3F] +
146 | lookup[(tmp << 2) & 0x3F] +
147 | '='
148 | )
149 | }
150 |
151 | return parts.join('')
152 | }
--------------------------------------------------------------------------------
/src/configure/customized/encrypt/lib/encrypt.js:
--------------------------------------------------------------------------------
1 | import encUtf8 from 'crypto-js/enc-utf8'
2 | import aes from 'crypto-js/aes'
3 | import ecb from 'crypto-js/mode-ecb'
4 | import pako from 'pako'
5 | import base64js from './base64js.min.js'
6 | import Util from '../../../../lib/common/index.js'
7 |
8 | var encryptType = 0
9 |
10 | var reqt = ''
11 |
12 | function getSpv (lib, appid, libVersion) {
13 | var policyversion = ''
14 | var appversion = ''
15 | var spv = lib + '|' + appid + '|' + libVersion + '|' + policyversion + '|' + appversion
16 | return encodeURIComponent(Util.encode(spv))
17 | }
18 |
19 | function encryptKey (lib, appid, libVersion) {
20 | reqt = +new Date()
21 | var orgkey = lib + appid + libVersion + reqt
22 | var base64Str = ''
23 | // MD5+base64+切割为数组
24 | var baseStr = Util.encode(Util.MD5(orgkey, 32).toUpperCase()).split('')
25 | var F = libVersion.split('.')
26 | var F1 = F[F.length - 1]
27 | var F2 = F[F.length - 2]
28 | if (!(Number(F2) % 2) === false) {
29 | // 倒叙
30 | base64Str = baseStr.reverse()
31 | } else {
32 | base64Str = baseStr
33 | }
34 | var key = ''
35 | for (var i = 0; i < base64Str.length; i++) {
36 | // 偶数位
37 | if (i % 2 === 0 && !(Number(F1) % 2 === 0)) {
38 | key += base64Str[i]
39 | } else if (!(i % 2 === 0) && Number(F1) % 2 === 0) {
40 | key += base64Str[i]
41 | }
42 | }
43 | if (key.length < 16) {
44 | key += key.split('').reverse().join('')
45 | }
46 | return key.slice(0, 16)
47 | }
48 |
49 | function getEncryptData (data, lib, appid, libVersion) {
50 | var key = encryptKey(lib, appid, libVersion)
51 | key = encUtf8.parse(key)
52 | var encryptData = ''
53 | if (encryptType === 1) {
54 | encryptData = aes.encrypt(data, key, {
55 | mode: ecb
56 | })
57 | }
58 | if (encryptType === 2) {
59 | var iv = encUtf8.parse('Analysys_315$CBC')
60 | encryptData = aes.encrypt(data, key, {
61 | iv: iv
62 | })
63 | }
64 | encryptData = encryptData.ciphertext.toString().toUpperCase()
65 | var pakoZip = pako.gzip(encryptData)
66 | return base64js.fromByteArray(pakoZip)
67 | }
68 |
69 | function encryptInit (config) {
70 | if (config.encryptType === 1) {
71 | encryptType = 1
72 | }
73 | if (config.encryptType === 2) {
74 | encryptType = 2
75 | }
76 |
77 | return config
78 | }
79 |
80 | function uploadData (option) {
81 | if (encryptType !== 1 && encryptType !== 2) {
82 | return option
83 | }
84 | var dataArray = JSON.parse(option.data)
85 | var lib = dataArray[0].xcontext.$lib
86 | var appid = dataArray[0].appid
87 | var libVersion = dataArray[0].xcontext.$lib_version
88 | option.data = getEncryptData(option.data, lib, appid, libVersion)
89 | option.url += '&spv=' + getSpv(lib, appid, libVersion) + '&reqt=' + reqt + '&reqv=' + encryptType
90 |
91 | return option
92 | }
93 |
94 | function zipInflate (data) {
95 | return JSON.parse(pako.inflate(base64js.toByteArray(data), {
96 | to: 'string'
97 | }))
98 | }
99 | window.AnalysysModule = Util.objMerge(window.AnalysysModule || {}, {
100 | encryptInit: encryptInit,
101 | uploadData: uploadData,
102 | zipInflate: zipInflate
103 | })
104 | export {
105 | encryptInit,
106 | uploadData,
107 | zipInflate
108 | }
109 |
--------------------------------------------------------------------------------
/src/configure/customized/heatmap/configure/fieldRules.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 字段填充、字段校验规则模板
3 | *
4 | * check:数据合法检测方法列表,每个方法返回bool值,以用户为准,同名覆盖
5 | *
6 | */
7 | import {
8 | getPageWidth,
9 | getPageHeight,
10 | getClickX,
11 | getClickY,
12 | getElementPath,
13 | getUrlPath,
14 | getElementX,
15 | getElementY,
16 | getElementType,
17 | getElementClickable,
18 | getEleContent,
19 | getDeviceType,
20 | getElementId,
21 | getElementName,
22 | getElementClassName,
23 | getElementTargetUrl
24 | } from '../lib/getField.js'
25 | export default {
26 | autoHeatmap: {
27 | check: {
28 | value: ['isBoolean']
29 | }
30 | },
31 | xcontext: {
32 | $page_width: {
33 | valueType: 0,
34 | value: getPageWidth
35 | },
36 | $page_height: {
37 | valueType: 0,
38 | value: getPageHeight
39 | },
40 | $click_x: {
41 | valueType: 0,
42 | value: getClickX
43 | },
44 | $click_y: {
45 | valueType: 0,
46 | value: getClickY
47 | },
48 | $element_path: {
49 | valueType: 0,
50 | value: getElementPath
51 | },
52 | $url_path: {
53 | valueType: 0,
54 | value: getUrlPath
55 | },
56 | $element_x: {
57 | valueType: 0,
58 | value: getElementX
59 | },
60 | $element_y: {
61 | valueType: 0,
62 | value: getElementY
63 | },
64 | $element_type: {
65 | valueType: 0,
66 | value: getElementType
67 | },
68 | $element_clickable: {
69 | valueType: 0,
70 | value: getElementClickable
71 | },
72 | $element_content: {
73 | valueType: 0,
74 | value: getEleContent
75 | },
76 | $device_type: {
77 | valueType: 0,
78 | value: getDeviceType
79 | },
80 | $element_id: {
81 | valueType: 0,
82 | value: getElementId
83 | },
84 | $element_name: {
85 | valueType: 0,
86 | value: getElementName
87 | },
88 | $element_target_url: {
89 | valueType: 0,
90 | value: getElementTargetUrl
91 | },
92 | $element_class_name: {
93 | valueType: 0,
94 | value: getElementClassName
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/configure/customized/heatmap/configure/fieldTemplate.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SDK 基础字段定义表
3 | * base.outer:上报日志基础结构定义
4 | * base.xcontext:上报报文找中xcontext下的共有字段定义
5 | * $开头的字段为各个事件特殊拥有字段
6 | */
7 | export default {
8 | $web_click: {
9 | xcontext: [
10 | '$page_width',
11 | '$page_height',
12 | '$click_x',
13 | '$click_y',
14 | '$element_path',
15 | '$url_path',
16 | '$url',
17 | '$title',
18 | '$session_id',
19 | '$device_type',
20 | '$session_id',
21 | '$is_time_calibrated',
22 | '$element_x',
23 | '$element_y',
24 | '$element_type',
25 | '$element_clickable',
26 | '$element_content',
27 | '$is_first_day',
28 | '$element_id',
29 | '$element_name',
30 | '$element_target_url',
31 | '$element_class_name'
32 | ]
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/configure/customized/heatmap/configure/lifecycle.js:
--------------------------------------------------------------------------------
1 | import { heatmapInit } from '../lib/heatmap.js'
2 |
3 | export default {
4 | AnalysysAgent: {
5 | init: heatmapInit
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/configure/customized/heatmap/heatmapSDK/common/config.js:
--------------------------------------------------------------------------------
1 | import Util from '../../../../../lib/common/index.js'
2 | import Storage from '../../../../../lib/storage/index.js'
3 |
4 | var heatmapConfig = window.ARK_HEATMAP && window.ARK_HEATMAP.config
5 | var ifarmeMessageList = []
6 | var showMapConfig = {
7 | type: 'heatmap',
8 | content: {},
9 | control: {},
10 | contentText: {},
11 | isRefresh: false,
12 | max: 10,
13 | rightMaxNum: 100
14 | }
15 |
16 | function backParam () {
17 | var params = {
18 | content: showMapConfig.content,
19 | times: +new Date() + (Storage.getLocal('ANSSERVERTIME') ? Number(Storage.getLocal('ANSSERVERTIME')) : 0)
20 | }
21 | params.content.requestType = 'web'
22 |
23 | params.content.appKey = heatmapConfig.appid
24 | if (!params.content.deviceType) {
25 | params.content.deviceType = Util.deviceType()
26 | }
27 | if (showMapConfig.isRefresh === true) {
28 | params.content.useCache = false
29 | } else {
30 | params.content.useCache = true
31 | }
32 | // if (!params.content["dbUrlDomain"]) {
33 | // var urlPath = params.content["urlDomain"] || params.content["urlPath"]
34 | // if (!urlPath) {
35 | // urlPath = location.protocol + '//' + location.host + location.pathname + location.hash
36 | // urlPath = urlPath.split('?')[0]
37 | // }
38 | // // urlPath = urlPath.split('#')[0]
39 | // params.content["urlDomain"] = params.content["urlPath"] = urlPath
40 | // }
41 |
42 | showMapConfig.isRefresh = false
43 | params.content = JSON.stringify(params.content)
44 |
45 | var param = []
46 | for (var key in params) {
47 | param.push(key + '=' + encodeURIComponent(params[key]))
48 | }
49 | param = param.join('&')
50 | return param
51 | }
52 | export {
53 | heatmapConfig,
54 | ifarmeMessageList,
55 | showMapConfig,
56 | backParam
57 | }
58 |
--------------------------------------------------------------------------------
/src/configure/customized/heatmap/heatmapSDK/common/iframeMsg.js:
--------------------------------------------------------------------------------
1 | import Util from '../../../../../lib/common/index.js'
2 | import { heatmapConfig } from './config.js'
3 |
4 | /**
5 | * [sendMsg description]发送热图SDK初始化完毕信息
6 | * @return {[type]} [description]
7 | */
8 | function sendMsg () {
9 | var msg = JSON.stringify({
10 | code: 'ark/heatmap',
11 | appkey: heatmapConfig.appid
12 | })
13 | // console.log('发送热图SDK初始化完毕消息===>', msg)
14 | window.parent.postMessage(msg, '*')
15 | }
16 |
17 | /**
18 | * [getMsg description]接收iframe消息
19 | * @param {Function} callback [description]
20 | * @return {[type]} [description]
21 | */
22 | function getMsg (callback) {
23 | Util.addEvent(window, 'message', function (msgObj) {
24 | var msg = msgObj.data
25 | // console.log('获取服务端热图命令===>', JSON.stringify(msgObj.data))
26 |
27 | try {
28 | if (Util.paramType(msg) === 'String') {
29 | msg = JSON.parse(msg)
30 | }
31 | } catch (e) { }
32 | callback(msg)
33 | })
34 | }
35 | export {
36 | sendMsg,
37 | getMsg
38 | }
39 |
--------------------------------------------------------------------------------
/src/configure/customized/heatmap/heatmapSDK/heatMap/nav.js:
--------------------------------------------------------------------------------
1 | import Util from '../../../../../lib/common/index.js'
2 |
3 | function bindHeadToggle () {
4 | var arkHead = document.getElementById('ARK_HEATMAP_HEAD')
5 | var openHead = document.getElementById('ARK_OPEN')
6 | var closeHead = document.getElementById('ARK_CLOSE')
7 |
8 | function toggleHead () {
9 | // event.stopPropagation();
10 | arkHead.style.top = Math.abs(arkHead.offsetTop) - arkHead.clientHeight + 'px'
11 | if (openHead.style.display === 'block') {
12 | openHead.style.display = 'none'
13 | } else {
14 | openHead.style.display = 'block'
15 | }
16 | }
17 | Util.addEvent(openHead, 'click', toggleHead)
18 | Util.addEvent(closeHead, 'click', toggleHead)
19 | }
20 |
21 | function initHead () {
22 | // 绑定头部显示隐藏
23 | bindHeadToggle()
24 | }
25 |
26 | export { initHead }
27 |
--------------------------------------------------------------------------------
/src/configure/customized/heatmap/heatmapSDK/lib/colorRange.js:
--------------------------------------------------------------------------------
1 | function ColorRangeMaker (option) {
2 | var vRange = option.value[1] - option.value[0]
3 | if (option.color.length === 2) { // 仅有两个颜色
4 | var rA = (option.color[1][0] - option.color[0][0]) / vRange
5 | var gA = (option.color[1][1] - option.color[0][1]) / vRange
6 | var bA = (option.color[1][2] - option.color[0][2]) / vRange
7 | this.option = {
8 | vRange: vRange,
9 | rA: rA,
10 | gA: gA,
11 | bA: bA,
12 | option: option
13 | }
14 | } else { // 两个以上颜色
15 | var makers = []
16 | var vA = vRange / (option.color.length - 1)
17 | for (var i = 1; i < option.color.length; i++) {
18 | var maker = new ColorRangeMaker({
19 | color: [option.color[i - 1], option.color[i]],
20 | value: [option.value[0] + vA * (i - 1),
21 | option.value[0] + vA * i
22 | ]
23 | })
24 | makers.push(maker)
25 | }
26 | this.option = { makers, vA, option }
27 | }
28 | }
29 |
30 | ColorRangeMaker.prototype.make = function (value) {
31 | var makers = this.option.makers
32 | var rA = this.option.rA
33 | var gA = this.option.gA
34 | var bA = this.option.bA
35 | var vA = this.option.vA
36 | var option = this.option.option
37 | if (value < option.value[0]) {
38 | return option.color[0]
39 | } else if (value > option.value[option.value.length - 1]) {
40 | return option.color[option.color.length - 1]
41 | } else {
42 | if (option.color.length === 2) { // 仅有两个颜色
43 | var color = option.color[0].map(a => a)
44 | var vATmp = value - option.value[0]
45 | color[0] += parseInt(rA * vATmp)
46 | color[1] += parseInt(gA * vATmp)
47 | color[2] += parseInt(bA * vATmp)
48 | return color
49 | } else {
50 | for (var i = 1; i < option.color.length; i++) {
51 | if (value <= option.value[0] + vA * i) {
52 | return makers[i - 1].make(value)
53 | }
54 | }
55 | }
56 | }
57 | }
58 | export default ColorRangeMaker
59 |
--------------------------------------------------------------------------------
/src/configure/customized/heatmap/heatmapSDK/webstay/webStayDom.js:
--------------------------------------------------------------------------------
1 | var webStayPageLineTemp = `
{LINENUM}%
2 | `
3 | var webStayMouseLineTemp = `
4 | `
5 | export { webStayPageLineTemp, webStayMouseLineTemp }
6 |
--------------------------------------------------------------------------------
/src/configure/customized/heatmap/heatmapSDK/webstay/webStayLine.css:
--------------------------------------------------------------------------------
1 | .ARK_PAGE_LINE_BOX {
2 | z-index: 1000000000;
3 | position: absolute;
4 | width: 100%;
5 | height: 1px;
6 | /*overflow-x:hidden;*/
7 | }
8 |
9 | .ARK_PAGE_LINE_LINE {
10 | width: 100%;
11 | height: 0px;
12 | border-bottom: dashed 1px #262d39 !important;
13 | }
14 |
15 | .ARK_PAGE_LINE_VALUE {
16 | /*width: 76px;
17 | height: 32px;*/
18 | background-color: #262d39;
19 | font-family: Roboto-Bold;
20 | font-size: 16px;
21 | font-weight: normal;
22 | font-stretch: normal;
23 | line-height: 16px;
24 | letter-spacing: 0px;
25 | color: #ffffff;
26 | padding: 8px 16px;
27 | border-radius: 0 4px 0 0;
28 | -moz-border-radius: 0 4px 0 0;
29 | position: absolute;
30 | left: 0;
31 | bottom: 0;
32 | }
33 |
34 | .ARK_MOUSE_LINE_VALUE {
35 | position: relative;
36 | left: -50%;
37 | text-align: center;
38 | padding: 8px 16px;
39 | border-radius: 4px;
40 | -moz-border-radius: 4px;
41 | background-color: #262d39;
42 | font-family: Roboto-Bold;
43 | font-size: 16px;
44 | font-weight: normal;
45 | font-stretch: normal;
46 | line-height: 16px;
47 | letter-spacing: 0px;
48 | color: #ffffff;
49 | }
50 | .ARK_MOUSE_LINE_LINE{
51 | border-bottom: solid 1px #262d39 !important;
52 | }
53 | .ARK_MOUSE_LINE_VALUE_BOX{
54 | left: 50%;
55 | position: absolute;
56 | top:-16px;
57 | }
--------------------------------------------------------------------------------
/src/configure/customized/heatmap/index.js:
--------------------------------------------------------------------------------
1 | import fieldRules from './configure/fieldRules.js'
2 | import fieldTemplate from './configure/fieldTemplate.js'
3 | import lifecycle from './configure/lifecycle.js'
4 | export {
5 | fieldRules,
6 | fieldTemplate,
7 | lifecycle
8 | }
9 |
--------------------------------------------------------------------------------
/src/configure/customized/heatmap/lib/elementContent.js:
--------------------------------------------------------------------------------
1 | import Util from '../../../../lib/common/index.js'
2 |
3 | function getElementContent (ele, status) {
4 | var eleContent = ''
5 | if (ele.tagName.toLowerCase() === 'input') {
6 | eleContent = ele.value || ''
7 | } else if (ele.tagName.toLowerCase() === 'img') {
8 | eleContent = ele.getAttribute('alt') || ele.getAttribute('title') || ''
9 | } else if (ele.tagName.toLowerCase() === 'a') {
10 | eleContent = ele.getAttribute('title') || ''
11 | }
12 | if (!eleContent) {
13 | var children = ele.childNodes
14 | for (var i = 0; i < children.length; i++) {
15 | if (children[i].nodeType === 3) {
16 | eleContent += children[i].nodeValue
17 | }
18 | }
19 | // if (ele.textContent) {
20 | // eleContent = Util.trim(ele.textContent)
21 | // } else {
22 | // if (ele.innerText) {
23 | // eleContent = Util.trim(ele.innerText)
24 | // }
25 | // }
26 | }
27 | if (eleContent && Util.paramType(eleContent) === 'String') {
28 | eleContent = eleContent.replace(/[\r\n]/g, ' ').replace(/[ ]+/g, ' ')
29 | } else {
30 | eleContent = ''
31 | }
32 | if (ele.tagName.toLowerCase() === 'input' && ele.type !== 'button' && ele.type !== 'submit' && status !== true) {
33 | return ''
34 | }
35 | eleContent = Util.trim(eleContent)
36 | // if (eleContent.length > 0) {
37 | // eleContent =
38 | // }
39 | return eleContent
40 | }
41 | export { getElementContent }
42 |
--------------------------------------------------------------------------------
/src/configure/customized/heatmap/lib/getField.js:
--------------------------------------------------------------------------------
1 | import Util from '../../../../lib/common/index.js'
2 | import { getElementContent } from './elementContent.js'
3 | import baseConfig from '../../../../lib/baseConfig/index.js'
4 | var elePostion = {
5 | ele: '',
6 | click_x: 0,
7 | click_y: 0,
8 | clickEle: ''
9 | }
10 |
11 | function domParentList (ele) {
12 | var list = []
13 | var parent = ele
14 | while (parent != null) {
15 | var index = 0
16 | if (parent.parentNode) {
17 | var clildrenEles = parent.parentNode.children
18 | if (clildrenEles) {
19 | for (var i = 0; i < clildrenEles.length; i++) {
20 | if (clildrenEles[i] === parent) {
21 | index = i
22 | }
23 | }
24 | }
25 | }
26 | var tagName = parent.tagName
27 | if (!tagName) {
28 | parent = parent.parentNode
29 | continue
30 | }
31 | tagName = tagName.toLowerCase()
32 | var parentID = parent.id ? ('#' + parent.id) : ''
33 | var eleClassNameList = parent.className && Util.paramType(parent.className) === 'String' ? parent.className.split(' ') : []
34 |
35 | if (eleClassNameList.length > 0) {
36 | var eleClassName = ''
37 | for (var y = 0; y < eleClassNameList.length; y++) {
38 | if (eleClassNameList[y] && eleClassNameList[y].indexOf('ARK') < 0) {
39 | eleClassName += '.' + eleClassNameList[y]
40 | }
41 | }
42 | list.push(tagName + parentID + eleClassName + '|' + index)
43 | } else {
44 | list.push(tagName + parentID + '|' + index)
45 | }
46 |
47 | parent = parent.parentNode
48 | }
49 | return list.join('<')
50 | }
51 |
52 | function getPageWidth () {
53 | return document.documentElement.scrollWidth
54 | }
55 |
56 | function getPageHeight () {
57 | return document.documentElement.scrollHeight
58 | }
59 |
60 | function getClickX () {
61 | return elePostion.click_x
62 | }
63 |
64 | function getClickY () {
65 | return elePostion.click_y
66 | }
67 |
68 | function getElementPath () {
69 | return domParentList(elePostion.ele)
70 | }
71 |
72 | function getUrlPath () {
73 | var url = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.hash
74 | try {
75 | url = decodeURIComponent(url)
76 | } catch (e) { }
77 | if (baseConfig.base.isHybrid === true) {
78 | url = url.replace(/"/g, '\\"')
79 | }
80 | return url
81 | }
82 |
83 | function getElementX () {
84 | return elePostion.elementX
85 | }
86 |
87 | function getElementY () {
88 | return elePostion.elementY
89 | }
90 |
91 | function getElementType () {
92 | return elePostion.ele.tagName.toLowerCase()
93 | }
94 |
95 | function getElementClick () {
96 | return Util.paramType(elePostion.ele.onclick) === 'Function'
97 | }
98 | function getElementAttrClick () {
99 | return elePostion.ele && elePostion.ele.getAttribute('data-ark-click') !== null
100 | }
101 |
102 | function checkElementConfig (eleConfig) {
103 | if (!eleConfig || (Util.paramType(eleConfig) === 'Array' && eleConfig.length === 0) || (Util.paramType(eleConfig) === 'String' && eleConfig === '')) {
104 | return false
105 | }
106 | var ele = elePostion.ele
107 | if (Util.paramType(eleConfig) === 'String') {
108 | var tagName = ele.tagName.toLowerCase()
109 | var className = Util.paramType(ele.className) === 'String' ? '.' + ele.className.split(' ').join('.') : ''
110 | var id = ele.id ? '#' + ele.id : ''
111 | if (tagName === eleConfig.toLowerCase() || className === eleConfig || id === eleConfig || tagName + className === eleConfig || tagName + id === eleConfig || id + className === eleConfig || tagName + id + className === eleConfig) {
112 | return true
113 | }
114 | } else if (Util.paramType(eleConfig) === 'Array') {
115 | for (var i = 0; i < eleConfig.length; i++) {
116 | if (checkElementConfig(eleConfig[i]) === true) {
117 | return true
118 | }
119 | }
120 | } else if (Util.paramType(eleConfig) === 'Function') {
121 | return eleConfig.call(eleConfig, ele) || false
122 | } else if (typeof eleConfig === 'object' && eleConfig === ele) {
123 | return true
124 | }
125 | return false
126 | }
127 | function getParentClickableElement () {
128 | var clickEle = elePostion.ele
129 | while (elePostion.ele != null) {
130 | if (elePostion.ele.nodeType !== 1) {
131 | elePostion.ele = elePostion.ele.parentNode
132 | continue
133 | }
134 |
135 | if (getElementClick() || getElementClickable() === 1 || getElementAttrClick() || checkElementConfig(baseConfig.base.trackList)) {
136 | clickEle = elePostion.ele
137 | break
138 | }
139 | elePostion.ele = elePostion.ele.parentNode
140 | }
141 | elePostion.ele = clickEle
142 | }
143 | /**
144 | * 判断当前元素是否为可触控元素
145 | */
146 | function getElementClickable () {
147 | var tagName = getElementType()
148 | var clickableElementList = ['a', 'button', 'input', 'select', 'textarea', 'svg'] // option无法触发点击事件
149 | if (clickableElementList.indexOf(tagName) > -1 || getElementAttrClick() || checkElementConfig(baseConfig.base.trackList)) {
150 | if (tagName === 'svg' && elePostion.ele.children && elePostion.ele.children.length > 0) {
151 | var svgIsClickable = 0
152 | var svgChildren = elePostion.ele.children
153 | for (var i = 0; i < svgChildren.length; i++) {
154 | if (svgChildren[i].tagName.toLowerCase() === 'use' &&
155 | (svgChildren[i].getAttribute('xlink:href') || getElementAttrClick() || checkElementConfig(baseConfig.base.trackList))) {
156 | svgIsClickable = 1
157 | }
158 | }
159 | return svgIsClickable
160 | }
161 | return 1
162 | }
163 | return 0
164 | }
165 |
166 | function getEleContent () {
167 | return getElementContent(elePostion.ele)
168 | }
169 |
170 | function getDeviceType () {
171 | return Util.deviceType()
172 | }
173 |
174 | function getElementId () {
175 | return elePostion.ele.id || elePostion.ele.getAttribute('id') || ''
176 | }
177 |
178 | function getElementName () {
179 | return elePostion.ele.getAttribute('name') || ''
180 | }
181 |
182 | function getElementClassName () {
183 | var eleClassName = elePostion.ele.getAttribute('class') || ''
184 | if (eleClassName) {
185 | var eleClassList = eleClassName.split(' ')
186 | var eleClassArray = []
187 | for (var i = 0; i < eleClassList.length; i++) {
188 | if (eleClassList[i] !== '') {
189 | eleClassArray.push(eleClassList[i])
190 | }
191 | }
192 | eleClassName = '.' + eleClassArray.join('.')
193 | return eleClassName
194 | }
195 | return ''
196 | }
197 |
198 | function getElementTargetUrl () {
199 | var href = elePostion.ele.getAttribute('href')
200 | if (href && href.indexOf('javascript:') < 0) {
201 | try {
202 | href = decodeURIComponent(href)
203 | } catch (e) { }
204 | if (baseConfig.base.isHybrid === true) {
205 | href = href.replace(/"/g, '\\"')
206 | }
207 | return href
208 | }
209 | return ''
210 | }
211 | export {
212 | elePostion,
213 | getPageWidth,
214 | getPageHeight,
215 | getClickX,
216 | getClickY,
217 | getElementPath,
218 | getUrlPath,
219 | getElementX,
220 | getElementY,
221 | getElementType,
222 | getElementClickable,
223 | getParentClickableElement,
224 | domParentList,
225 | getEleContent,
226 | getDeviceType,
227 | getElementId,
228 | getElementName,
229 | getElementClassName,
230 | getElementTargetUrl
231 | }
232 |
--------------------------------------------------------------------------------
/src/configure/customized/heatmap/lib/heatmap.js:
--------------------------------------------------------------------------------
1 | import Util from '../../../../lib/common/index.js'
2 | import { elePostion, getParentClickableElement } from './getField.js'
3 | import { eleScroll, eleOffset } from '../heatmapSDK/common/index.js'
4 | var heatmapConfig = {}
5 |
6 | function loadHeatmapSDK () {
7 | if (!document.body || !document.getElementsByTagName('body')[0]) {
8 | setTimeout(loadHeatmapSDK, 50)
9 | return
10 | }
11 | Util.addScript('AnalysysAgent_JS_SDK_HEATMAP', heatmapConfig.SDKFileDirectory)
12 | window.ARK_HEATMAP = {
13 | config: heatmapConfig
14 | }
15 | }
16 |
17 | // function offset (obj, direction) {
18 | // var fristText = direction.split('')[0]
19 | // // 将top,left首字母大写,并拼接成offsetTop,offsetLeft
20 | // var offsetDir = 'offset' + fristText.toUpperCase() + direction.substring(1)
21 |
22 | // var realNum = obj[offsetDir]
23 | // var positionParent = obj.offsetParent // 获取上一级定位元素对象
24 |
25 | // while (positionParent != null) {
26 | // realNum += positionParent[offsetDir]
27 | // positionParent = positionParent.offsetParent
28 | // }
29 | // return realNum
30 | // }
31 |
32 | function addClickEvent (event) {
33 | var e = event || window.event
34 | if (e.touches && e.touches.length > 0) {
35 | e = e.touches[0]
36 | }
37 | var ele = e.target || e.srcElement
38 |
39 | if (Util.checkTypeList(heatmapConfig.heatMapBlackList, ele) ||
40 | (heatmapConfig.heatMapWhiteList &&
41 | !Util.checkTypeList(heatmapConfig.heatMapWhiteList, ele))
42 | ) return
43 | // e.stopPropagation()
44 | // e.preventDefault()
45 | var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft
46 | var scrollY = document.documentElement.scrollTop || document.body.scrollTop
47 | var x = e.pageX || (e.clientX + scrollX)
48 | var y = e.pageY || (e.clientY + scrollY)
49 | elePostion.click_x = x
50 | elePostion.click_y = y
51 | elePostion.clickEle = elePostion.ele = ele
52 | getParentClickableElement()
53 | var eleScr = eleScroll(elePostion.ele)
54 | var eleOff = eleOffset(elePostion.ele)
55 | elePostion.elementX = x - (eleOff.left - eleScr.scrollLeft)
56 | elePostion.elementY = y - (eleOff.top - eleScr.scrollTop)
57 | if (!x || !y || x <= 0 || y <= 0) {
58 | return
59 | }
60 | if (!window.AnalysysAgent || !window.AnalysysAgent.freeApi) {
61 | setTimeout(function () {
62 | addClickEvent(event)
63 | }, 100)
64 | } else {
65 | window.AnalysysAgent.freeApi('$web_click')
66 | }
67 | }
68 |
69 | function initHeatmap () {
70 | if (Util.deviceType() == 'desktop') {
71 | Util.addEvent(document, 'click', addClickEvent)
72 | } else {
73 | Util.addEvent(document, 'touchstart', addClickEvent)
74 | }
75 | }
76 |
77 | function heatmapInit (config) {
78 | heatmapConfig = config
79 | if (window.location.href.indexOf('arkheatmap=true') > -1 || window.name.indexOf('arkheatmap=true') > -1) {
80 | if (window.name === '') {
81 | window.name = window.location.href
82 | }
83 | loadHeatmapSDK()
84 | } else if (config.autoHeatmap === true && config.isHybrid === false) {
85 | initHeatmap()
86 | }
87 | return config
88 | }
89 |
90 | export { heatmapInit }
91 |
--------------------------------------------------------------------------------
/src/configure/customized/mpaas/index.js:
--------------------------------------------------------------------------------
1 | import Util from '../../../lib/common/index.js'
2 | var moduleStatus = Util.isiOS === true ? true : false
3 | function isHybrid () {
4 | document.addEventListener("AlipayJSBridgeReady", function () {
5 | window.AlipayJSBridge.call('isHybrid', {}, function (msg) {
6 | if (msg === true) {
7 | // console.log('mPaas 启动Hybrid模式')
8 | checkAnalysys()
9 | }
10 | })
11 | })
12 | }
13 | function checkAnalysys () {
14 | if (window.AnalysysAgent && Util.paramType(window.AnalysysAgent.init) === 'Function') {
15 | var config = Util.objMerge(window.AnalysysAgent.config || {}, {
16 | isHybrid: true
17 | })
18 | window.AnalysysAgent.init(config)
19 | } else {
20 | setTimeout(checkAnalysys, 30)
21 | }
22 | }
23 | var checkNum = 0
24 | function checkBridge () {
25 | if (checkNum > 3) {
26 |
27 | if (checkNum > 5) {
28 | // console.log('mPaas Hybrid模式失败,为正常接入JS SDK')
29 | return
30 | } else if (window.AnalysysAgent && Util.paramType(window.AnalysysAgent.init) === 'Function') {
31 | window.AnalysysAgent.init({
32 | isARKH5: true
33 | })
34 | } else {
35 | checkNum++
36 | setTimeout(checkBridge, 300)
37 | }
38 | return
39 | }
40 | if (window.AlipayJSBridge) {
41 | isHybrid()
42 | } else {
43 | setTimeout(checkBridge, 300)
44 | }
45 | checkNum++
46 | }
47 | if (window.AnalysysAgent && !window.AnalysysAgent.isInit && moduleStatus === true) {
48 | checkBridge()
49 | }
50 |
51 | function upData (params) {
52 | // var callback = (function (params) {
53 | // return function (resulut) {
54 | // if (resulut.resulut === 'failure') {
55 | // BaseUpdata(params)
56 | // }
57 | // }
58 | // })(params)
59 | // window.AlipayJSBridge.call('analysysAgentCallNaitve', params, callback)
60 | BaseUpdata(params)
61 | }
62 | function BaseUpdata (params) {
63 | if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.AnalysysAgent) {
64 | window.webkit.messageHandlers.AnalysysAgent.postMessage(params)
65 | } else {
66 | var msg = JSON.stringify(params)
67 | var url = 'analysysagent:' + msg
68 | loadIframeUrl(url)
69 | }
70 | }
71 | function loadIframeUrl (url) {
72 | if (!document.body) {
73 | setTimeout(function () { loadIframeUrl(url) }, 200)
74 | return
75 | }
76 | var iframe = document.createElement('iframe')
77 | iframe.setAttribute('src', url)
78 | iframe.setAttribute('id', 'AnalysysAgentIframe')
79 | iframe.setAttribute('style', 'display:none;')
80 |
81 | document.body.appendChild(iframe)
82 | iframe.parentNode.removeChild(iframe)
83 | }
84 | function track (eventName, pro, elePostion) {
85 | window.AlipayJSBridge.call('AnalysysAgentTrack', { 'props': [eventName, JSON.stringify(pro), JSON.stringify(elePostion)] }, function () { });
86 |
87 | }
88 | function eventList () {
89 | window.AlipayJSBridge.call('AnalysysAgentGetEventList', {}, function () { });
90 |
91 | }
92 | function getPro (appRelateds, timeId) {
93 | window.AlipayJSBridge.call('AnalysysAgentGetProperty', { 'props': [JSON.stringify(appRelateds), timeId] }, function () { });
94 |
95 | }
96 | function onEvent (hybridKey, HybridAns) {
97 | return HybridAns[hybridKey]
98 | }
99 | window.AnalysysModule = Util.objMerge(window.AnalysysModule || {}, {
100 | moduleStatus: moduleStatus,
101 | isHybrid: isHybrid,
102 | upData: upData,
103 | track: track,
104 | eventList: eventList,
105 | getPro: getPro,
106 | onEvent: onEvent
107 | })
--------------------------------------------------------------------------------
/src/configure/customized/pageClose/index.js:
--------------------------------------------------------------------------------
1 | import Util from '../../../lib/common/index.js'
2 | var Version = '4.4.1'
3 |
4 | /**
5 | * @method pageEndTrack [发送页面关闭事件]
6 | * @param {Function} callback 发送数据后的回调函数
7 | */
8 | function pageEndTrack (callback) {
9 | var time = +new Date()
10 | if (isPageShow === false) {
11 | /**
12 | * 页面离开时间为 关闭时间-切换tab的时间+之前tab切换离开的时间
13 | */
14 | pageLeaveTime = time - pageHiddenTime + pageLeaveTime
15 | }
16 | /**
17 | * 页面停留时间为 当前时间 - 页面打开时间 - 页面隐藏时间
18 | */
19 |
20 | var pageStay = Number(time - pageStartTime - pageLeaveTime)
21 | if (pageStay < 0) {
22 | pageStay = Number(time - pageStartTime)
23 | }
24 | if (window.AnalysysAgent && window.AnalysysAgent.track) {
25 | window.AnalysysAgent.track('page_close', {
26 | pageStayTime: pageStay,
27 | $url: url,
28 | $title: pageTitle
29 | // sdkVersion: Version,
30 | // pageOpenTime: Util.format(new Date(pageOpenTime), 'yyyy-MM-dd hh:mm:ss.SSS')
31 | })
32 |
33 | Util.paramType(callback) === 'Function' && callback.call(callback, null)
34 | } else {
35 | }
36 | createTime()
37 | }
38 | /**
39 | * url标准化
40 | *
41 | * @returns url
42 | */
43 | function getUrl () {
44 | var url = window.location.href
45 | try {
46 | url = decodeURIComponent(url)
47 | } catch (e) { }
48 | try {
49 | if (window.AnalysysAgent.config.isHybrid === true) {
50 | url = url.replace(/"/g, '\\"')
51 | }
52 | } catch (e) { }
53 | return url
54 | }
55 | /**
56 | * 初始化参数
57 | */
58 | /**
59 | * @method createTime [初始化参数]
60 | */
61 | function createTime (startTime, title) {
62 | var time = +new Date()
63 | pageStartTime = startTime || time
64 | pageHiddenTime = startTime || time
65 | pageLeaveTime = 0
66 | isPageShow = true
67 | url = getUrl()
68 | pageTitle = arguments.length > 1 ? title : document.title
69 | }
70 | var pageOpenTime = +new Date()
71 | var pageStartTime = pageOpenTime
72 | var pageHiddenTime = pageOpenTime
73 | var pageLeaveTime = 0
74 | var isPageShow = true
75 | var url = getUrl()
76 | var pageTitle = document.title
77 | var autoPageClose = true
78 | /**
79 | * 监听页面打开与关闭事件
80 | */
81 | if ('onpageShow' in window) {
82 | Util.addEvent(window, 'pageShow', function () {
83 | pageStartTime = pageHiddenTime = +new Date()
84 | })
85 | Util.addEvent(window, 'pagehide', function () {
86 | if (autoPageClose === true) {
87 | pageEndTrack()
88 | }
89 | })
90 | } else {
91 | Util.addEvent(window, 'load', function () {
92 | pageStartTime = pageHiddenTime = +new Date()
93 | })
94 | Util.addEvent(window, 'beforeunload', function () {
95 | if (autoPageClose === true) {
96 | pageEndTrack()
97 | }
98 | })
99 | }
100 | /**
101 | * 监听离开/返回tab且未关闭页面
102 | */
103 | if ('onvisibilitychange' in document) {
104 | Util.addEvent(document, 'visibilitychange', function () {
105 | if (document.hidden) {
106 | isPageShow = false
107 | pageHiddenTime = +new Date()
108 | } else {
109 | isPageShow = true
110 | pageLeaveTime = +new Date() - pageHiddenTime + pageLeaveTime
111 | }
112 | })
113 | }
114 |
115 | function pageCloseInit (obj) {
116 | if (Util.paramType(obj) === 'Object' && Util.paramType(obj.autoPageClose) === 'Boolean') {
117 | autoPageClose = obj.autoPageClose
118 | }
119 | }
120 | window.AnalysysModule = Util.objMerge(window.AnalysysModule || {}, {
121 | pageClose: {
122 | Version: Version,
123 | pageEndTrack: pageEndTrack,
124 | init: pageCloseInit,
125 | createTime: createTime
126 | }
127 | })
128 | export { pageCloseInit, pageEndTrack }
129 |
--------------------------------------------------------------------------------
/src/configure/customized/userClick/configure/fieldRules.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 字段填充、字段校验规则模板
3 | *
4 | * check:数据合法检测方法列表,每个方法返回bool值,以用户为准,同名覆盖
5 | *
6 | */
7 | import {
8 | getPageWidth,
9 | getPageHeight,
10 | getElementPath,
11 | getUrlPath,
12 | getElementType,
13 | getElementClickable,
14 | getEleContent,
15 | getDeviceType,
16 | getElementId,
17 | getElementName,
18 | getElementClassName,
19 | getElementTargetUrl
20 | } from '../../heatmap/lib/getField.js'
21 | export default {
22 | xcontext: {
23 | $page_width: {
24 | valueType: 0,
25 | value: getPageWidth
26 | },
27 | $page_height: {
28 | valueType: 0,
29 | value: getPageHeight
30 | },
31 | $element_path: {
32 | valueType: 0,
33 | value: getElementPath
34 | },
35 | $url_path: {
36 | valueType: 0,
37 | value: getUrlPath
38 | },
39 | $element_type: {
40 | valueType: 0,
41 | value: getElementType
42 | },
43 | $element_clickable: {
44 | valueType: 0,
45 | value: getElementClickable
46 | },
47 | $element_content: {
48 | valueType: 0,
49 | value: getEleContent
50 | },
51 | $device_type: {
52 | valueType: 0,
53 | value: getDeviceType
54 | },
55 | $element_id: {
56 | valueType: 0,
57 | value: getElementId
58 | },
59 | $element_name: {
60 | valueType: 0,
61 | value: getElementName
62 | },
63 | $element_target_url: {
64 | valueType: 0,
65 | value: getElementTargetUrl
66 | },
67 | $element_class_name: {
68 | valueType: 0,
69 | value: getElementClassName
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/configure/customized/userClick/configure/fieldTemplate.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SDK 基础字段定义表
3 | * base.outer:上报日志基础结构定义
4 | * base.xcontext:上报报文找中xcontext下的共有字段定义
5 | * $开头的字段为各个事件特殊拥有字段
6 | */
7 | export default {
8 | $user_click: {
9 | xcontext: [
10 | // '$page_width',
11 | // '$page_height',
12 | '$url_path',
13 | '$url',
14 | '$title',
15 | '$is_first_day',
16 | '$session_id',
17 | '$is_time_calibrated',
18 | '$device_type',
19 | '$element_type',
20 | '$element_path',
21 | '$element_content',
22 | '$element_id',
23 | '$element_name',
24 | '$element_target_url',
25 | '$element_class_name'
26 | ]
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/configure/customized/userClick/configure/lifecycle.js:
--------------------------------------------------------------------------------
1 | import { userClickInit } from '../lib/userClick.js'
2 |
3 | export default {
4 | AnalysysAgent: {
5 | init: userClickInit
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/configure/customized/userClick/index.js:
--------------------------------------------------------------------------------
1 | import fieldRules from './configure/fieldRules.js'
2 | import fieldTemplate from './configure/fieldTemplate.js'
3 | import lifecycle from './configure/lifecycle.js'
4 | export {
5 | fieldRules,
6 | fieldTemplate,
7 | lifecycle
8 | }
9 |
--------------------------------------------------------------------------------
/src/configure/customized/userClick/lib/userClick.js:
--------------------------------------------------------------------------------
1 | import Util from '../../../../lib/common/index.js'
2 | import {
3 | getElementClickable,
4 | elePostion,
5 | getParentClickableElement,
6 | } from '../../heatmap/lib/getField.js'
7 | var userClickConfig = {}
8 |
9 | function addClickEvent (event) {
10 | var e = event || window.event
11 | if (e.touches && e.touches.length > 0) {
12 | e = e.touches[0]
13 | }
14 | var ele = e.target || e.srcElement
15 | if (Util.checkTypeList(userClickConfig.autoClickBlackList, ele) ||
16 | (userClickConfig.autoClickWhiteList &&
17 | !Util.checkTypeList(userClickConfig.autoClickWhiteList, ele))) return
18 | elePostion.ele = ele
19 | getParentClickableElement()
20 | if (getElementClickable() !== 1) return
21 | var config = userClickConfig.user_click_property
22 | var userClickPro = {}
23 | if (Util.paramType(config) === 'Object') {
24 | for (var key in config) {
25 | if (Util.paramType(config[key]) === 'Function') {
26 | config[key] = config[key].call(config[key], ele)
27 | }
28 | }
29 | userClickPro = config
30 | } else if (Util.paramType(config) === 'Function') {
31 | userClickPro = config.call(config, ele)
32 | }
33 |
34 | var property = elePostion.ele.getAttribute('data-ark-click') || {}
35 | if (Util.paramType(property) === 'String') {
36 | try {
37 | property = JSON.parse(property)
38 | } catch (e) { }
39 | }
40 | if (Util.paramType(property) !== 'Object') {
41 | property = {}
42 | }
43 | if (Util.paramType(userClickPro) === 'Object') {
44 | property = Util.objMerge(userClickPro, property)
45 | }
46 | window.AnalysysAgent.freeApi('$user_click', property)
47 | }
48 |
49 | function addListenerUserClick () {
50 | if (Util.deviceType() === 'desktop') {
51 | Util.addEvent(document, 'mousedown', addClickEvent)
52 | } else {
53 | Util.addEvent(document, 'touchstart', addClickEvent)
54 | }
55 | }
56 |
57 | function userClickInit (config) {
58 | userClickConfig = config
59 | if (config.autoTrack === true) {
60 | addListenerUserClick()
61 | }
62 | return config
63 | }
64 |
65 |
66 | export { userClickInit }
67 |
--------------------------------------------------------------------------------
/src/configure/customized/visual/configure/fieldRules.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 字段填充、字段校验规则模板
3 | *
4 | * check:数据合法检测方法列表,每个方法返回bool值,以用户为准,同名覆盖
5 | *
6 | */
7 | export default {
8 | 'visitorConfigURL ': {
9 | check: {
10 | value: ['isUrl']
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/configure/customized/visual/configure/fieldTemplate.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SDK 基础字段定义表
3 | * base.outer:上报日志基础结构定义
4 | * base.xcontext:上报报文找中xcontext下的共有字段定义
5 | * $开头的字段为各个事件特殊拥有字段
6 | */
7 | export default {
8 | }
9 |
--------------------------------------------------------------------------------
/src/configure/customized/visual/configure/lifecycle.js:
--------------------------------------------------------------------------------
1 | import { visitorInit } from '../lib/visitor.js'
2 | export default {
3 | AnalysysAgent: {
4 | init: visitorInit
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/configure/customized/visual/index.js:
--------------------------------------------------------------------------------
1 | import fieldRules from './configure/fieldRules.js'
2 | import fieldTemplate from './configure/fieldTemplate.js'
3 | import lifecycle from './configure/lifecycle.js'
4 | export {
5 | fieldRules,
6 | fieldTemplate,
7 | lifecycle
8 | }
9 |
--------------------------------------------------------------------------------
/src/configure/customized/visual/visualShow/common/boxMove.js:
--------------------------------------------------------------------------------
1 | import Util from '../../../../../lib/common/index.js'
2 |
3 | function MoveBox () {
4 | var _this = this
5 | this.ele = null
6 | this.parent = null
7 | this.parentOption = {
8 | x: 0,
9 | y: 0
10 | }
11 | this.touchOption = {
12 | x: 0,
13 | y: 0
14 | }
15 |
16 | function down (event) {
17 | event.preventDefault()
18 | var touch
19 | if (event.touches) {
20 | touch = event.touches[0]
21 | } else {
22 | touch = event
23 | }
24 |
25 | _this.touchOption = {
26 | x: touch.clientX,
27 | y: touch.clientY
28 | }
29 | _this.parentOption = {
30 | x: _this.parent.offsetLeft,
31 | y: _this.parent.offsetTop
32 | }
33 | Util.addEvent(document, 'touchmove', function () {
34 | event.preventDefault()
35 | }, false)
36 | Util.addEvent(document, 'mousemove', move, false)
37 | Util.addEvent(document, 'mouseup', end, false)
38 |
39 | Util.addEvent(document, 'touchmove', move, false)
40 | Util.addEvent(document, 'touchend', end, false)
41 | }
42 |
43 | function move (event) {
44 | var touch
45 | if (event.touches) {
46 | touch = event.touches[0]
47 | } else {
48 | touch = event
49 | }
50 | var x = _this.parentOption.x + touch.clientX - _this.touchOption.x
51 | var y = _this.parentOption.y + touch.clientY - _this.touchOption.y
52 |
53 | _this.parent.style.left = x + 'px'
54 | _this.parent.style.top = y + 'px'
55 | // _this.parentOption = {
56 | // x: x,
57 | // y: y
58 | // }
59 | }
60 |
61 | function end (event) {
62 | Util.removeEvent(document, 'touchmove', function () {
63 | event.preventDefault()
64 | }, false)
65 |
66 | Util.removeEvent(document, 'touchmove', move, false)
67 | Util.removeEvent(document, 'touchend', end, false)
68 |
69 | Util.removeEvent(document, 'mousemove', move, false)
70 | Util.removeEvent(document, 'mouseup', end, false)
71 | }
72 | this.init = function (ele) {
73 | this.ele = ele
74 | this.parent = this.ele.parentNode
75 |
76 | Util.addEvent(_this.ele, 'mousedown', down, false)
77 | Util.addEvent(_this.ele, 'touchstart', down, false)
78 | }
79 |
80 | this.remove = function () {
81 | if (!this.ele) return
82 | Util.removeEvent(document, 'mousedown', down, false)
83 | Util.removeEvent(document, 'touchstart', down, false)
84 | }
85 | }
86 | export default new MoveBox()
87 |
--------------------------------------------------------------------------------
/src/configure/customized/visual/visualShow/common/config.js:
--------------------------------------------------------------------------------
1 | var visualConfig = window.ARK_VISUAL && window.ARK_VISUAL.config
2 |
3 | export { visualConfig }
4 |
--------------------------------------------------------------------------------
/src/configure/customized/visual/visualShow/common/iframeMsg.js:
--------------------------------------------------------------------------------
1 | import Util from '../../../../../lib/common/index.js'
2 |
3 | /**
4 | * [sendMsg description]发送热图SDK初始化完毕信息
5 | * @return {[type]} [description]
6 | */
7 | function sendMsg (msg) {
8 | console.log('发送可视化SDK初始化完毕消息===>', JSON.stringify(msg, null, 2))
9 |
10 | if (Util.paramType(msg) === 'Object') {
11 | msg = JSON.stringify(msg)
12 | }
13 | window.parent.postMessage(msg, '*')
14 | }
15 |
16 | /**
17 | * [getMsg description]接收iframe消息
18 | * @param {Function} callback [description]
19 | * @return {[type]} [description]
20 | */
21 | function getMsg (callback) {
22 | Util.addEvent(window, 'message', function (msgObj) {
23 | var msg = msgObj.data
24 | try {
25 | if (Util.paramType(msg) === 'String') {
26 | msg = JSON.parse(msg)
27 | }
28 | } catch (e) { }
29 | console.log('获取可视化消息===>', JSON.stringify(msg, null, 2))
30 | callback(msg)
31 | })
32 | }
33 | export {
34 | sendMsg,
35 | getMsg
36 | }
37 |
--------------------------------------------------------------------------------
/src/configure/customized/visual/visualShow/index.js:
--------------------------------------------------------------------------------
1 | import { isElmentReady } from './common/index.js'
2 | import { visualConfig } from './common/config.js'
3 | import { sendMsg } from './common/iframeMsg.js'
4 | import { addVisualListener, delEvents, showVisualEvent, delVisualEvent, openVisualEvent, hiddenVisualEvent, backProInputList, openDebugModule, openDebugEvent, setVisualStatus } from './visual/index.js'
5 | // import { addDebugListener, removeDebugListener, openDebugBox, delDebugBox, hiddenDebugEvent } from './debug/index.js'
6 | import Util from '../../../../lib/common/index.js'
7 | var isVisaulInit = true
8 | var visualStatus = false
9 | var highlightStatus = true
10 |
11 | /**
12 | * 监听服务端iframeMessage消息
13 | *
14 | * @param {JSON} msg 消息
15 | */
16 | function processMsg (msg) {
17 | if (!isVisaulInit) {
18 | return
19 | }
20 | var eventList = []
21 | var type = msg.type
22 | // var url = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.hash
23 | switch (type) {
24 | case 'INIT': // 初始化验证
25 | if (msg.appid !== visualConfig.appid) {
26 | sendMsg({
27 | code: 400,
28 | type: 'INIT',
29 | msg: 'appkey不相同'
30 | })
31 | isVisaulInit = false
32 | return
33 | }
34 | sendMsg({
35 | code: 200,
36 | type: 'INIT',
37 | isNewVisual: true
38 | })
39 | var obj = {
40 | type: 'checkUrl',
41 | code: 200,
42 | url: window.location.href,
43 | skip: true
44 | }
45 | sendMsg(obj)
46 | setVisualStatus(msg.isNewVisual || false)
47 | sendChangeUrl()
48 | break
49 | case 'point_list': // 所有已埋点元素绑定debug模式
50 |
51 | eventList = msg.data || []
52 | if (highlightStatus === false) {
53 | return
54 | }
55 | if (!isElmentReady() || document.readyState !== 'complete') {
56 | setTimeout(function () {
57 | processMsg(msg)
58 | }, 1000)
59 | return
60 | } else {
61 | var pageList = showVisualEvent(eventList)
62 | sendMsg({
63 | type: 'check_points',
64 | list: pageList
65 | })
66 | }
67 | break
68 | // case 'EVENT_URL':
69 | // // 验证埋点元素是否为当前页元素
70 |
71 | // var eventUrlObj = {
72 | // type: 'checkUrl',
73 | // code: 200,
74 | // url: url,
75 | // skip: msg.url === url
76 | // }
77 | // sendMsg(eventUrlObj)
78 | // break
79 | case 'VISUAL':
80 | if (highlightStatus === false) {
81 | visualStatus = msg.visual || false
82 | return
83 | }
84 | if (msg.visual === true) {
85 | // 开始初始化可视化埋点
86 | openDebugModule(false)
87 |
88 | } else if (msg.debugmode === true) {
89 | // 开始初始化debug模式
90 | openDebugModule(true)
91 | }
92 | if (highlightStatus === true) {
93 | addVisualListener()
94 | }
95 | break
96 | case 'change_update':
97 | if (highlightStatus === false) {
98 | return
99 | }
100 | if (msg.path && msg.path.length > 0) {
101 | // if (msg.path[0].url.charAt(msg.path[0].url.length - 1) === '/' && url.charAt(url.length - 1) !== '/') {
102 | // url += '/'
103 | // }
104 | // if (url !== msg.path[0].url) {
105 | // sendMsg({
106 | // type: 'change_page',
107 | // code: 200,
108 | // msg: '跳转埋点页面',
109 | // path: msg.path,
110 | // url: url
111 | // })
112 | // } else {
113 | openVisualEvent(msg.path[0])
114 | // }
115 | }
116 | break
117 | case 'change_delete':
118 | if (visualStatus === false) {
119 | openDebugModule(false)
120 | }
121 |
122 | if (msg.path && msg.path.length > 0) {
123 | delVisualEvent(msg.path[0])
124 | sendMsg({
125 | code: 200,
126 | type: 'change_delete'
127 | })
128 | } else {
129 | sendMsg({
130 | code: 400,
131 | type: 'change_delete',
132 | msg: '删除失败'
133 | })
134 | }
135 | break
136 | case 'add_success':
137 | sendMsg({
138 | code: 200,
139 | type: 'add_success',
140 | msg: '添加成功'
141 | })
142 | break
143 | case 'success_update':
144 | if (msg.path && msg.path.length > 0) {
145 | showVisualEvent(msg.path)
146 | }
147 | break
148 | case 'debug':
149 | // openDebugBox(msg)
150 | openDebugEvent(msg)
151 | break
152 | case 'highlight':
153 | highlightStatus = msg.highlight
154 | // if (highlightStatus === true) {
155 | // showVisualEvent(eventList)
156 | // }
157 | // if (visualStatus) {
158 | hiddenVisualEvent(highlightStatus)
159 |
160 | // } else {
161 | // hiddenVisualEvent(highlightStatus)
162 |
163 | // }
164 | break
165 | case 'like_pro':
166 | backProInputList(msg)
167 | break
168 | }
169 | }
170 | /**
171 | * [initHeatmap description]初始化可视化并建立通讯
172 | * @return {[type]} [description]
173 | */
174 | function initVisual () {
175 | Util.changeHash(function () {
176 | highlightStatus = true
177 | visualStatus = true
178 | delEvents()
179 | hiddenVisualEvent(true)
180 | sendChangeUrl()
181 | })
182 | }
183 | // }
184 | function sendChangeUrl () {
185 | // var url = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.hash
186 | sendMsg({
187 | type: 'change_page_now',
188 | code: 200,
189 | msg: '跳转埋点页面',
190 | url: window.location.href.replace('?visual=true&', '?').replace('?visual=true', '')
191 | })
192 | }
193 | if (window.ARK_VISUAL) {
194 | initVisual()
195 | }
196 | window.AnalysysModule = Util.objMerge(window.AnalysysModule || {}, {
197 | visual: {
198 | init: initVisual,
199 | msg: processMsg,
200 | version: '4.5.1'
201 | }
202 | })
--------------------------------------------------------------------------------
/src/configure/customized/visual/visualShow/templete/debug.js:
--------------------------------------------------------------------------------
1 | var debugTemp = '' +
2 | '
' +
3 | '
{LOGLIST}
' +
4 | '
' +
5 | '
'
6 |
7 | function setDebugTemp (config) {
8 | if (!config) return
9 |
10 | var list = ''
11 | for (var i = 0; i < config.list.length; i++) {
12 | list += '' + config.list[i].title + ':' + config.list[i].val + '
'
13 | }
14 | var temp = debugTemp.replace('{TOP}', config.top)
15 | .replace('{LEFT}', config.left)
16 | .replace('{LOGLIST}', list)
17 | return temp
18 | }
19 | export { setDebugTemp }
20 |
--------------------------------------------------------------------------------
/src/configure/customized/webstay/configure/fieldRules.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 字段填充、字段校验规则模板
3 | *
4 | * check:数据合法检测方法列表,每个方法返回bool值,以用户为准,同名覆盖
5 | *
6 | */
7 | import { getViewPortWidth, getViewPortHeight, getScrollTop, getDuration, getDeviceType } from '../lib/getField.js'
8 | export default {
9 | autoWebstay: {
10 | check: {
11 | value: ['isBoolean']
12 | }
13 | },
14 | xcontext: {
15 | $viewport_width: {
16 | valueType: 0,
17 | value: getViewPortWidth
18 | },
19 | $viewport_position: {
20 | valueType: 0,
21 | value: getScrollTop
22 | },
23 | $viewport_height: {
24 | valueType: 0,
25 | value: getViewPortHeight
26 | },
27 | $event_duration: {
28 | valueType: 0,
29 | value: getDuration
30 | },
31 | $device_type: {
32 | valueType: 0,
33 | value: getDeviceType
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/configure/customized/webstay/configure/fieldTemplate.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SDK 基础字段定义表
3 | * base.outer:上报日志基础结构定义
4 | * base.xcontext:上报报文找中xcontext下的共有字段定义
5 | * $开头的字段为各个事件特殊拥有字段
6 | */
7 | export default {
8 | $webstay: {
9 | xcontext: [
10 | '$referrer',
11 | '$referrer_domain',
12 | '$title',
13 | '$url',
14 | '$viewport_width',
15 | '$viewport_position',
16 | '$viewport_height',
17 | '$event_duration',
18 | '$device_type',
19 | '$session_id',
20 | '$is_time_calibrated',
21 | '$is_first_day'
22 | ]
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/configure/customized/webstay/configure/lifecycle.js:
--------------------------------------------------------------------------------
1 | import { autoWebstayInit } from '../lib/autoWebstay.js'
2 |
3 | export default {
4 | AnalysysAgent: {
5 | init: autoWebstayInit
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/configure/customized/webstay/index.js:
--------------------------------------------------------------------------------
1 | import fieldRules from './configure/fieldRules.js'
2 | import fieldTemplate from './configure/fieldTemplate.js'
3 | import lifecycle from './configure/lifecycle.js'
4 | export {
5 | fieldRules,
6 | fieldTemplate,
7 | lifecycle
8 | }
9 |
--------------------------------------------------------------------------------
/src/configure/customized/webstay/lib/autoWebstay.js:
--------------------------------------------------------------------------------
1 | import Util from '../../../../lib/common/index.js'
2 | import { isElmentReady } from '../../heatmap/heatmapSDK/common/index.js'
3 | import { setRootEle } from './getField.js'
4 | var interval = null
5 | var topValue = 0
6 |
7 | function initWebStay () {
8 | // var scroll = window.onscroll
9 | // window.onscroll = function () {
10 | // if (scroll && Util.paramType(scroll) === 'Function') {
11 | // scroll()
12 | // }
13 | // clearTimeout(interval)
14 | // interval = setTimeout(isScroll, 1000)
15 | // topValue = document.documentElement.scrollTop || document.body.scrollTop
16 | // }
17 | function getScroll () {
18 | if (isRoot === true) {
19 | return document.documentElement.scrollTop || document.body.scrollTop
20 | } else {
21 | return rootEle.scrollTop || 0
22 | }
23 | }
24 | function isScroll () {
25 | var m2 = getScroll()
26 | if (topValue === m2) {
27 | clearTimeout(interval)
28 | interval = null
29 |
30 | if (!window.AnalysysAgent || !window.AnalysysAgent.freeApi) {
31 | setTimeout(function () { isScroll() }, 100)
32 | } else {
33 | window.AnalysysAgent.freeApi('$webstay')
34 | }
35 | }
36 | }
37 | Util.addEvent(rootEle, 'scroll', function () {
38 | clearTimeout(interval)
39 | interval = setTimeout(isScroll, 1000)
40 | topValue = getScroll()
41 | })
42 | // setTimeout(startScroll, 1000)
43 | }
44 |
45 | // function startScroll () {
46 | // if (!window.AnalysysAgent || !window.AnalysysAgent.freeApi || !document.body) {
47 | // setTimeout(function () { startScroll() }, 100)
48 | // } else {
49 | // var fristScrollTop = document.documentElement.scrollTop || document.body.scrollTop
50 | // if (fristScrollTop === 0) {
51 |
52 | // window.AnalysysAgent.freeApi('$webstay')
53 | // }
54 | // }
55 | // }
56 | function getChildEle (ele) {
57 | var parentEle = ele || document.body
58 | var childList = parentEle.childNodes
59 | var scrollEle = document.body
60 | for (var i = 0; i < childList.length; i++) {
61 | if (childList[i].nodeType === 1) {
62 | if (hasScrollbar(childList[i]) === true) {
63 | isRoot = false
64 | return childList[i]
65 | } else {
66 | scrollEle = getChildEle(childList[i])
67 | }
68 | }
69 | }
70 | return scrollEle
71 | }
72 | function hasScrollbar (ele) {
73 |
74 | var scrollHeight = 0
75 | var innerHeight = 0
76 | var baseHeight = document.body.scrollHeight
77 | if (ele) {
78 | scrollHeight = ele.scrollHeight
79 | innerHeight = ele.clientHeight
80 | } else {
81 | scrollHeight = document.body.scrollHeight
82 | innerHeight = window.innerHeight || document.documentElement.clientHeight
83 | }
84 | return scrollHeight > innerHeight && scrollHeight > baseHeight
85 | }
86 |
87 | var rootEle = null
88 | var isRoot = true
89 | function getRootEle (config) {
90 | var userEle = null
91 |
92 | if (config.autoHeatmap === true && config.autoWebstay === true && config.isHybrid === false) {
93 | var webstayRootEleConfig = config.webstayRootEle
94 |
95 | if (webstayRootEleConfig) {
96 | if (Util.paramType(webstayRootEleConfig) === 'String') {
97 | var eleList = Util.selectorAllEleList(webstayRootEleConfig)
98 | if (eleList.length > 0) {
99 | userEle = eleList[0]
100 | }
101 | } else if (Util.paramType(webstayRootEleConfig) === 'Function') {
102 | userEle = webstayRootEleConfig.call(webstayRootEleConfig) || null
103 | } else if (typeof webstayRootEleConfig === 'object' && webstayRootEleConfig.nodeType === 1) {
104 | userEle = webstayRootEleConfig
105 | }
106 | }
107 | if (userEle) {
108 | isRoot = false
109 | rootEle = userEle
110 | } else {
111 | rootEle = getChildEle()
112 | }
113 | if (rootEle === document.body || !rootEle) {
114 | rootEle = window
115 | }
116 | setRootEle(rootEle)
117 | initWebStay()
118 | }
119 |
120 | }
121 | function autoWebstayInit (config) {
122 | if (window.location.href.indexOf('visual=true') > -1 || window.location.href.indexOf('arkheatmap=true') > -1) {
123 | return config
124 | }
125 | if (isElmentReady() === false) {
126 | setTimeout(function () {
127 | autoWebstayInit(config)
128 | }, 300)
129 | } else {
130 | getRootEle(config)
131 | }
132 | return config
133 | }
134 |
135 | export { autoWebstayInit }
136 |
--------------------------------------------------------------------------------
/src/configure/customized/webstay/lib/getField.js:
--------------------------------------------------------------------------------
1 | import Util from '../../../../lib/common/index.js'
2 | import conifg from '../../../../lib/baseConfig/index.js'
3 | var startDate = +new Date()
4 | var root = null
5 |
6 | function setRootEle (ele) {
7 | if (ele) {
8 | root = ele
9 | } else {
10 | root = document.body
11 | }
12 | }
13 | // 获取浏览器窗口的可视区域的宽度
14 | function getViewPortWidth () {
15 | return document.documentElement.clientWidth || document.body.clientWidth
16 | }
17 |
18 | // 获取浏览器窗口的可视区域的高度
19 | function getViewPortHeight () {
20 | return document.documentElement.clientHeight || document.body.clientHeight
21 | }
22 |
23 | // 获取浏览器窗口垂直滚动条的位置
24 | function getScrollTop () {
25 | return root.scrollTop || document.documentElement.scrollTop || document.body.scrollTop
26 | }
27 |
28 | function getDuration () {
29 | var nowTime = +new Date()
30 | var duration = nowTime - startDate
31 | startDate = nowTime
32 | if (Util.paramType(conifg.base.webstayDuration) === 'Number' && conifg.base.webstayDuration > 0) {
33 | if (duration > conifg.base.webstayDuration) {
34 | return conifg.base.webstayDuration
35 | }
36 | } else {
37 | if (duration > 5 * 60 * 60 * 1000) {
38 | return 5 * 60 * 60 * 1000
39 | }
40 | }
41 | return duration
42 | }
43 | function getDeviceType () {
44 | return Util.deviceType()
45 | }
46 | export { getViewPortWidth, getViewPortHeight, getScrollTop, getDuration, getDeviceType, setRootEle }
47 |
--------------------------------------------------------------------------------
/src/configure/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 合并定制模块
3 | *
4 | * base:基础模块
5 | * encrypt:数据加密模块
6 | * visitor:可视化模块
7 | * webstay:深度线采集模块
8 | * zh:招行模块
9 | * heatmap:热图采集及展示模块
10 | * device:设备信息模块
11 | * ua:上报ua模块
12 | * errorLog:校验失败上报$errorLog模块
13 | */
14 | import * as base from './base/index.js'
15 | import * as webstay from './customized/webstay/index.js'
16 | import * as heatmap from './customized/heatmap/index.js'
17 | import * as ua from './customized/UA/index.js'
18 | import * as userClick from './customized/userClick/index.js'
19 | import Util from '../lib/common/index.js'
20 |
21 | var plugList = [webstay, heatmap, ua, userClick]
22 | /**
23 | * 合并定制化模板 根据输入模板列表不同集合出不同的定制化模板
24 | */
25 | var fieldRules = base.fieldRules || {}
26 | var fieldTemplate = base.fieldTemplate || {}
27 | var lifecycle = base.lifecycle || {}
28 | for (var i = 0; i < plugList.length; i++) {
29 | if (plugList[i].fieldRules) {
30 | fieldRules = Util.objMerge(fieldRules, plugList[i].fieldRules)
31 | }
32 | if (plugList[i].fieldTemplate) {
33 | fieldTemplate = Util.objMerge(fieldTemplate, plugList[i].fieldTemplate)
34 | }
35 | if (plugList[i].lifecycle) {
36 | lifecycle = Util.fnMerge(lifecycle, plugList[i].lifecycle)
37 | }
38 | }
39 | export { fieldRules, fieldTemplate, lifecycle }
40 |
--------------------------------------------------------------------------------
/src/lib/baseConfig/index.js:
--------------------------------------------------------------------------------
1 | import fieldTemplate from '../../configure/base/fieldTemplate.js'
2 | export default {
3 | base: {
4 | appid: '', // APPID
5 | $debug: 0, // debug状态
6 | uploadURL: '', // 上传地址
7 | auto: true, // 自动采集页面打开
8 | autoProfile: true, //自动采集用户首次属性
9 | hash: true, // 自动采集单页面应用
10 | autoWebstay: true, // 自动采集访问深度
11 | singlePage: true, // 自动采集单页面应用
12 | pageProperty: {}, // 自动采集页面打开时页面自定义属性
13 | $lib_version: '4.5.6', // sdk版本号
14 | cross_subdomain: true, // 跨子域存储cookie
15 | cross_subdomain_super: true, // 同步跨子域存储cookie时 同步通用属性
16 | allowTimeCheck: false, // ajax上报日志 开启时间校准
17 | isHybrid: false, // 是否为Hybrid模式
18 | getDataTimeout: 10000, // 获取数据超时时间
19 | sendDataTimeout: 10000,// 上报数据超时时间
20 | isMessageSDK: false
21 | },
22 | status: {
23 | code: 200,
24 | FnName: '',
25 | key: '',
26 | value: '',
27 | errorCode: '',
28 | successCode: ''
29 | },
30 | keywords: fieldTemplate.base.xcontext,
31 | baseJson: fieldTemplate.base.outer,
32 | sendNum: 1800,
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/lib/checkField/index.js:
--------------------------------------------------------------------------------
1 | import Util from '../common/index.js'
2 | import baseConfig from '../baseConfig/index.js'
3 | var CheckField = function () {
4 |
5 | }
6 | CheckField.prototype = Util
7 |
8 | CheckField.prototype.isString = function (val) {
9 | baseConfig.status.errorCode = '60001'
10 | return Util.paramType(val) === 'String'
11 | }
12 | CheckField.prototype.isNumber = function (val) {
13 | baseConfig.status.errorCode = '60002'
14 | return Util.paramType(val) === 'Number'
15 | }
16 | CheckField.prototype.isBoolean = function (val) {
17 | baseConfig.status.errorCode = '60003'
18 | return Util.paramType(val) === 'Boolean'
19 | }
20 | CheckField.prototype.isObject = function (val) {
21 | return this.paramType(val) === 'Object'
22 | }
23 | CheckField.prototype.lengthRule = function (val, min, max) {
24 | if (!this.isNumber(max)) {
25 | max = Infinity
26 | }
27 | var status = true
28 |
29 | if (!(this.isNumber(min) && val.length && val.length > min && val.length < max + 1)) {
30 | baseConfig.status.errorCode = '60005'
31 | status = false
32 | }
33 |
34 | return status
35 | }
36 | CheckField.prototype.nimLength = function (val) {
37 | return this.lengthRule(val, 0)
38 | }
39 | CheckField.prototype.length99 = function (val) {
40 | var lengthStatus = this.lengthRule(val, 0, 99)
41 | if (!lengthStatus) {
42 | baseConfig.status.errorCode = '600010'
43 | }
44 | return lengthStatus
45 | }
46 | CheckField.prototype.length125 = function (val) {
47 | var lengthStatus = this.lengthRule(val, 0, 125)
48 | if (!lengthStatus) {
49 | baseConfig.status.errorCode = '60009'
50 | }
51 | return lengthStatus
52 | }
53 | CheckField.prototype.length255 = function (val) {
54 | if (!val && !this.isString(val) && !this.isNumber(val) && !this.isBoolean(val)) {
55 | baseConfig.status.errorCode = '60005'
56 | return false
57 | }
58 | if (this.paramType(val) !== 'String') {
59 | val = val.toString()
60 | }
61 | var lengthStatus = this.lengthRule(val, 0, 255)
62 | if (!lengthStatus) {
63 | baseConfig.status.errorCode = '600019'
64 | }
65 | return lengthStatus
66 | }
67 | CheckField.prototype.keyLength255 = function (val) {
68 | var lengthStatus = this.length255(val)
69 | if (!lengthStatus) {
70 | baseConfig.status.errorCode = '600017'
71 | }
72 | return lengthStatus
73 | }
74 |
75 | CheckField.prototype.isUrl = function (URL) {
76 | var str = URL
77 | // 判断URL地址的正则表达式为:http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?
78 | // 下面的代码中应用了转义字符"\"输出一个字符"/"
79 | var Expression = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- ./?%&=]*)?/
80 | var objExp = new RegExp(Expression)
81 | if (objExp.test(str) === true) {
82 | return true
83 | } else {
84 | baseConfig.status.errorCode = '60006'
85 | return false
86 | }
87 | }
88 |
89 | CheckField.prototype.isDebug = function (val) {
90 | if (this.isNumber(val) && (val === 0 || val === 1 || val === 2)) {
91 | return true
92 | }
93 | return false
94 | }
95 | CheckField.prototype.notObject = function (val) {
96 | var status = !this.isObject(val)
97 | if (!status) {
98 | baseConfig.status.errorCode = '600020'
99 | }
100 | return status
101 | }
102 |
103 | CheckField.prototype.notSpecialCharacters = function (val) {
104 | var patrn = new RegExp('[\\u4E00-\\u9FA5]|[\\uFE30-\\uFFA0]', 'gi')
105 | var reg = /^[$a-zA-Z][a-zA-Z0-9_$]{0,}$/
106 | if (patrn.test(val) || !reg.test(val)) {
107 | baseConfig.status.errorCode = '600011'
108 | return false
109 | }
110 | return true
111 | }
112 | CheckField.prototype.isArrayString = function (val) {
113 | if (this.paramType(val) === 'Array') {
114 | for (var i = 0; i < val.length; i++) {
115 | if (this.paramType(val[i]) !== 'String') {
116 | baseConfig.status.errorCode = '600013'
117 | return false
118 | }
119 | if (!this.length255(val[i])) {
120 | if (val[i] && val[i].length > 500) {
121 | val[i] = Util.stringSlice(val[i], 499) + '$'
122 | }
123 | baseConfig.status.value = val[i]
124 | return false
125 | }
126 | }
127 | }
128 | return true
129 | }
130 | CheckField.prototype.keywords = function (val) {
131 | var key = baseConfig.keywords
132 | if (key.indexOf(val) > -1) {
133 | baseConfig.status.errorCode = '600012'
134 | return false
135 | }
136 | return true
137 | }
138 |
139 | export default new CheckField()
140 |
--------------------------------------------------------------------------------
/src/lib/compatible/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 兼容低版本API
3 | */
4 | function ieCreat () {
5 | if (!Array.prototype.indexOf) {
6 | Array.prototype.indexOf = function (elt /*, from */) {
7 | var len = this.length >>> 0
8 | var from = Number(arguments[1]) || 0
9 | from = (from < 0)
10 | ? Math.ceil(from)
11 | : Math.floor(from)
12 | if (from < 0) { from += len }
13 | for (; from < len; from++) {
14 | if (from in this &&
15 | this[from] === elt) { return from }
16 | }
17 | return -1
18 | }
19 | }
20 | }
21 |
22 | export { ieCreat }
23 |
--------------------------------------------------------------------------------
/src/lib/fillField/UTM.js:
--------------------------------------------------------------------------------
1 | import Util from '../common/index.js'
2 | var UTM = {
3 | utm_campaign_id: Util.GetUrlParam('campaign_id'),
4 | utm_source: Util.GetUrlParam('utm_source') || Util.GetUrlParam('hmsr'),
5 | utm_medium: Util.GetUrlParam('utm_medium') || Util.GetUrlParam('hmpl'),
6 | utm_term: Util.GetUrlParam('utm_term') || Util.GetUrlParam('hmkw'),
7 | utm_content: Util.GetUrlParam('utm_content') || Util.GetUrlParam('hmci'),
8 | utm_campaign: Util.GetUrlParam('utm_campaign') || Util.GetUrlParam('hmcu')
9 | }
10 | function clearUTM () {
11 | UTM = {
12 | utm_campaign_id: '',
13 | utm_source: '',
14 | utm_medium: '',
15 | utm_term: '',
16 | utm_content: '',
17 | utm_campaign: ''
18 | }
19 | }
20 | export { UTM, clearUTM }
21 |
--------------------------------------------------------------------------------
/src/lib/fillField/deviceType.js:
--------------------------------------------------------------------------------
1 | var ua = window.navigator.userAgent.toLowerCase()
2 |
3 | function isPhone () {
4 | var isMobile = /Mobile(\/|\s)/.test(ua)
5 |
6 | // Either:
7 | // - iOS but not iPad
8 | // - Android 2
9 | // - Android with "Mobile" in the UA
10 |
11 | return /(iPhone|iPod)/.test(ua) ||
12 | (!/(Silk)/.test(ua) && (/(Android)/.test(ua) && (/(Android 2)/.test(ua) || isMobile))) ||
13 | (/(BlackBerry|BB)/.test(ua) && isMobile) ||
14 | /(Windows Phone)/.test(ua)
15 | }
16 |
17 | function isTablet () {
18 | return !isPhone() && (/iPad/.test(ua) || /Android/.test(ua) || /(RIM Tablet OS)/.test(ua) ||
19 | (/MSIE 10/.test(ua) && /; Touch/.test(ua)))
20 | }
21 |
22 | function isMobile () {
23 | if (isPhone()) {
24 | return 'phone'
25 | }
26 | if (isTablet()) {
27 | return 'tablet'
28 | }
29 | return 'desktop'
30 | }
31 | var deviceType = isMobile() || ''
32 | export { deviceType }
33 |
--------------------------------------------------------------------------------
/src/lib/fillField/getField.js:
--------------------------------------------------------------------------------
1 | import baseConfig from '../baseConfig/index.js'
2 | import Util from '../common/index.js'
3 | import Storage from '../storage/index.js'
4 | import sessionId from './sessionId.js'
5 | import { checkSpider } from './spider.js'
6 | import { UTM, clearUTM } from './UTM.js'
7 |
8 | import { getId, getUUId, getAliasId, getIdentifyId } from './id.js'
9 |
10 | var base = baseConfig.base
11 |
12 | function appkey (appkey) {
13 | base.appid = appkey
14 | }
15 |
16 | function getAppId () {
17 | return base.appid
18 | }
19 |
20 | function debugMode (debug) {
21 | base.$debug = debug
22 | }
23 |
24 | function getDebugMode () {
25 | return base.$debug
26 | }
27 |
28 | function uploadURL (url) {
29 | if (url.charAt(url.length - 1) !== '/') {
30 | url += '/'
31 | }
32 | base.uploadURL = url
33 | }
34 |
35 | function getUploadURL () {
36 | if (base.uploadURL.charAt(base.uploadURL.length - 1) !== '/') {
37 | base.uploadURL += '/'
38 | }
39 | return base.uploadURL
40 | }
41 |
42 | function nowDate () {
43 | return +new Date() + (Storage.getLocal('ANSSERVERTIME') ? Number(Storage.getLocal('ANSSERVERTIME')) : 0)
44 | }
45 |
46 | function timeCalibration () {
47 | if (Storage.getLocal('ANSSERVERTIME')) {
48 | return true
49 | }
50 | return false
51 | }
52 |
53 | function getXwhat () {
54 | return baseConfig.status.FnName
55 | }
56 |
57 | function isLogin () {
58 | var status = false
59 | if (getAliasId() || Storage.getLocal('ARK_TRACK_LOGIN')) {
60 | status = true
61 | }
62 | return status
63 | }
64 |
65 | var timeZone = 'GMT' + Util.clientTimeZone()
66 |
67 | var language = (navigator.language || navigator.browserLanguage).toLowerCase()
68 |
69 | // var device_type = deviceType
70 |
71 | function getSessionId () {
72 | return sessionId.getId()
73 | }
74 |
75 | function isFirstTime () {
76 | var timeStatus = Storage.getLocal('FRISTIME')
77 | Storage.setLocal('FRISTIME', false)
78 | return timeStatus
79 | }
80 |
81 | function isFirstDay () {
82 | var todayDate = Util.format(new Date(), 'yyyyMMdd')
83 | var storageDay = Storage.getLocal('FRISTDAY')
84 | if (storageDay && todayDate !== storageDay) {
85 | return false
86 | }
87 | // Storage.setLocal("FRISTDAY", todayDate)
88 | return true
89 | }
90 |
91 | function originalId () {
92 | return getIdentifyId() || getUUId()
93 | }
94 | var referrer = document.referrer || ''
95 | function setReferrer (ref) {
96 | referrer = ref
97 | }
98 | function getReferrer () {
99 | var refer = referrer
100 | try {
101 | refer = decodeURIComponent(referrer)
102 | } catch (e) { }
103 | if (baseConfig.base.isHybrid === true) {
104 | refer = refer.replace(/"/g, '\\"')
105 | }
106 | return refer
107 | }
108 |
109 | function getReferrerDomain () {
110 | return Util.getDomainFromUrl(false, referrer)
111 | }
112 |
113 | function getTitle () {
114 | return document.title
115 | }
116 |
117 | function startupTime () {
118 | return Storage.getSession('STARTUPTIME') || ''
119 | }
120 |
121 | function getUrl () {
122 | var url = window.location.href
123 | try {
124 | url = decodeURIComponent(url)
125 | } catch (e) { }
126 | if (baseConfig.base.isHybrid === true) {
127 | url = url.replace(/"/g, '\\"')
128 | }
129 | return url
130 | }
131 |
132 | function getLibVersion () {
133 | return base.$lib_version
134 | }
135 |
136 | function getScreenWidth () {
137 | var width = Util.paramType(Number(window.screen.width)) === 'Number' ? Number(window.screen.width) : 0
138 | return width
139 | }
140 |
141 | function getScreenHeight () {
142 | var height = Util.paramType(Number(window.screen.height)) === 'Number' ? Number(window.screen.height) : 0
143 | return height
144 | }
145 | /**
146 | * UTM参数控制逻辑
147 | * UTM参数改变切换session
148 | * UTM参数不满足条件 清空UTM参数
149 | */
150 |
151 | var oldUTM = Storage.getSession('ARK_UTM') || ''
152 |
153 | if (UTM.utm_campaign || UTM.utm_source || UTM.utm_medium || UTM.utm_campaign_id || UTM.utm_term || UTM.utm_content) {
154 | if (oldUTM !== JSON.stringify(UTM)) {
155 | sessionId.setId()
156 | }
157 | Storage.setSession('ARK_UTM', JSON.stringify(UTM))
158 | } else {
159 | clearUTM()
160 | Storage.removeSession('ARK_UTM')
161 | }
162 |
163 | function utmCampaignId () {
164 | return UTM.utm_campaign_id
165 | }
166 |
167 | function utmSource () {
168 | return UTM.utm_source
169 | }
170 |
171 | function utmMedium () {
172 | return UTM.utm_medium
173 | }
174 |
175 | function utmTerm () {
176 | return UTM.utm_term
177 | }
178 |
179 | function utmContent () {
180 | return UTM.utm_content
181 | }
182 |
183 | function utmCampaign () {
184 | return UTM.utm_campaign
185 | }
186 |
187 | export {
188 | getAppId,
189 | getId,
190 | getUploadURL,
191 | appkey,
192 | debugMode,
193 | uploadURL,
194 | getDebugMode,
195 | nowDate,
196 | getXwhat,
197 | isLogin,
198 | timeZone,
199 | language,
200 | getSessionId,
201 | isFirstTime,
202 | isFirstDay,
203 | originalId,
204 | getReferrer,
205 | getReferrerDomain,
206 | getTitle,
207 | getUrl,
208 | getScreenWidth,
209 | getScreenHeight,
210 | startupTime,
211 | checkSpider,
212 | getLibVersion,
213 | utmCampaignId,
214 | utmSource,
215 | utmMedium,
216 | utmTerm,
217 | utmContent,
218 | utmCampaign,
219 | timeCalibration,
220 | setReferrer
221 | // device_type
222 | }
223 |
--------------------------------------------------------------------------------
/src/lib/fillField/id.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 用户ID 操作集
3 | * ARK_LOGINID>ARK_TRACKID>ARK_ID
4 | */
5 | import Storage from '../storage/index.js'
6 | import Util from '../common/index.js'
7 |
8 | function getId () {
9 | var id = Storage.getLocal('ARK_LOGINID') || Storage.getLocal('ARK_TRACKID') || Storage.getLocal('ARK_ID')
10 | if (!id || id === '[object Object]') {
11 | id = setUUId()
12 | Storage.setLocal('ARK_ID', id)
13 | }
14 | // if(!Storage.getCookie("ARK_ID")){
15 | Storage.setCookie('ARK_ID', getIdentifyId() || getUUId())
16 | // }
17 | return id
18 | }
19 |
20 | function setUUId () {
21 | var timeRandom = (new Date().getTime()).toString() + (Math.random() * 10000).toString()
22 | var id = 'JS' + Util.MD5((timeRandom).toString(), 32) + Util.MD5((timeRandom).toString(), 32).slice(0, 4)
23 |
24 | // var storageId = Storage.getCookie("ARK_ID")
25 | // if (storageId && storageId.length > 10) {
26 | // id = Storage.getCookie("ARK_ID")
27 | // }
28 | Storage.setCookie('ARK_ID', id)
29 | return id
30 | }
31 |
32 | function getUUId () {
33 | var id = Storage.getLocal('ARK_ID')
34 | if (!id) {
35 | id = setUUId()
36 | Storage.setLocal('ARK_ID', id)
37 | }
38 | return id
39 | }
40 |
41 | function removeUUId () {
42 | Storage.removeLocal('ARK_ID')
43 | }
44 |
45 | function setAliasId (id) {
46 | Storage.setLocal('ARK_LOGINID', id)
47 | }
48 |
49 | function getAliasId () {
50 | return Storage.getLocal('ARK_LOGINID')
51 | }
52 |
53 | function removeAliasId () {
54 | Storage.removeLocal('ARK_LOGINID')
55 | }
56 |
57 | function setIdentifyId (id) {
58 | Storage.setLocal('ARK_TRACKID', id)
59 | }
60 |
61 | function getIdentifyId () {
62 | return Storage.getLocal('ARK_TRACKID')
63 | }
64 |
65 | function removeIdentifyId () {
66 | Storage.removeLocal('ARK_TRACK_LOGIN')
67 | Storage.removeLocal('ARK_TRACKID')
68 | }
69 |
70 | export {
71 | getId,
72 | setUUId,
73 | getUUId,
74 | removeUUId,
75 | setAliasId,
76 | getAliasId,
77 | removeAliasId,
78 | setIdentifyId,
79 | getIdentifyId,
80 | removeIdentifyId
81 | }
82 |
--------------------------------------------------------------------------------
/src/lib/fillField/index.js:
--------------------------------------------------------------------------------
1 | import Util from '../common/index.js'
2 | import baseConfig from '../baseConfig/index.js'
3 | import Storage from '../storage/index.js'
4 | import { errorLog, successLog } from '../printLog/index.js'
5 | import checkRule from '../checkField/index.js'
6 | import { fieldRules } from '../../configure/index.js'
7 | import sessionId from './sessionId.js'
8 |
9 | import { removeAliasId, removeIdentifyId } from './id.js'
10 |
11 | function check (value, checkList) {
12 | for (var i = 0; i < checkList.length; i++) {
13 | var checkStatus = checkRule[checkList[i]](value)
14 | if (!checkStatus) {
15 | return false
16 | }
17 | }
18 | return true
19 | }
20 |
21 | function checkFields (key, value, rule) {
22 | var checkRule = rule.check
23 | var status = true
24 | if (!checkRule) {
25 | return status
26 | }
27 |
28 | var checkKey = checkRule.key
29 | var checkValue = checkRule.value || fieldRules.xcontextCommonRule.value
30 |
31 | if (checkKey) {
32 | baseConfig.status.code = 200
33 | status = check(key, checkKey)
34 | baseConfig.status.key = key
35 | if (!status) {
36 | baseConfig.status.code = 400
37 | errorLog()
38 | }
39 | }
40 |
41 | if (checkValue) {
42 | baseConfig.status.code = 200
43 | status = check(value, checkValue)
44 | if (Util.paramType(value) !== 'Array') {
45 | baseConfig.status.value = value
46 | }
47 | if (!status) {
48 | baseConfig.status.code = 400
49 | errorLog()
50 | }
51 | }
52 |
53 | // if (status && checkRule.successCode) {
54 | // baseConfig.status.successCode = checkRule.successCode
55 | // }
56 | return status
57 | }
58 |
59 | function resetCode () {
60 | baseConfig.status = {
61 | code: 200,
62 | FnName: baseConfig.status.FnName,
63 | key: '',
64 | value: '',
65 | errorCode: '',
66 | successCode: ''
67 | }
68 | }
69 |
70 | function fillField (feilds, rules) {
71 | var rulesList = rules || fieldRules
72 | var obj = {}
73 | for (var key in feilds) {
74 | var feild = feilds[key]
75 | var rule = rulesList[key]
76 | if (!rule) {
77 | continue
78 | }
79 | var feildValue = ''
80 |
81 | if (Util.paramType(feild) === 'Object') {
82 | var content = fillField(feild, rule)
83 | obj[key] = content
84 | } else {
85 | if (Util.objHasKay(rule, 'valueType')) {
86 | if (rule.valueType === 0) {
87 | feildValue = rule.value()
88 | if (Util.paramType(feildValue) === 'String' && feildValue.length > 500) {
89 | obj[key] = Util.stringSlice(feildValue, 499) + '$'
90 | } else {
91 | obj[key] = feildValue
92 | }
93 | // }
94 | // }
95 | }
96 |
97 | if (rule.valueType === 1) {
98 | feildValue = rule.value
99 |
100 | // if (checkFields(key, feildValue, rule)) {
101 | // obj[key] = feildValue
102 | // } else {
103 | // if (baseConfig.status.errorCode === '600019') {
104 | if (Util.paramType(feildValue) === 'String' && feildValue.length > 500) {
105 | obj[key] = Util.stringSlice(feildValue, 499) + '$'
106 | } else {
107 | obj[key] = feildValue
108 | }
109 | // }
110 | // }
111 | }
112 | }
113 | }
114 | }
115 | return obj
116 | }
117 | /**
118 | * [reset description]检测是否重置初始化状态
119 | * @return {[type]} [description] true:需初始化 false:无需初始化
120 | */
121 | function clearCache (resetStatus) {
122 | resetStatus = resetStatus || false
123 | if (!resetStatus) {
124 | var config = baseConfig.base
125 | for (var key in config) {
126 | if (Util.paramType(config[key]) !== 'Object') {
127 | if (key === '$debug' || key === 'appid' || key === 'uploadURL') {
128 | var keyStorage = Storage.getLocal('ANS' + key.toUpperCase())
129 | if (keyStorage !== config[key]) {
130 | resetStatus = true
131 | }
132 | if (resetStatus) {
133 | Storage.setLocal('ANS' + key.toUpperCase(), config[key])
134 | }
135 | }
136 | }
137 | }
138 | }
139 | if (resetStatus) {
140 | removeAliasId()
141 | removeIdentifyId()
142 | Storage.removeLocal('ARKSUPER')
143 | Storage.removeSession('STARTUP')
144 | Storage.setLocal('FRISTDAY', Util.format(new Date(), 'yyyyMMdd'))
145 | Storage.setLocal('FRISTIME', true)
146 | Storage.removeLocal('POSTDATA')
147 | Storage.removeLocal('ANSSERVERTIME')
148 | Storage.removeLocal('ARKFRISTPROFILE')
149 | }
150 | return resetStatus
151 | }
152 | /**
153 | * [isStartUp description]检测启动状态
154 | * @return {Boolean} [description] true:已启动,false:未启动
155 | */
156 | function isStartUp () {
157 | var startUpStatus = Storage.getSession('STARTUP') || false
158 | var cookieStartup = Storage.getCookie('ARK_STARTUP')
159 | if (document.referrer !== '' && cookieStartup && baseConfig.base.cross_subdomain === true) {
160 | var cookieObj = JSON.parse(Util.decode(decodeURIComponent(cookieStartup)))
161 | var cookieStartUpStatus = cookieObj['STARTUP']
162 | var cookieStartUpTime = cookieObj['STARTUPTIME']
163 | Storage.setSession('STARTUP', cookieStartUpStatus)
164 | Storage.setSession('STARTUPTIME', cookieStartUpTime)
165 | // Storage.removeCookie('ARK_STARTUP', baseConfig.base.cross_subdomain, 'session')
166 | startUpStatus = Storage.getSession('STARTUP') || false
167 | }
168 | if (startUpStatus === false) {
169 | var startUpTime = Util.format(new Date(), 'yyyy-MM-dd hh:mm:ss.SSS')
170 | Storage.setSession('STARTUP', true)
171 | Storage.setSession('STARTUPTIME', startUpTime)
172 | sessionId.setId()
173 | if (baseConfig.base.cross_subdomain === true) {
174 | Storage.setCookie('ARK_STARTUP', encodeURIComponent(Util.encode(JSON.stringify({ 'STARTUP': true, 'STARTUPTIME': startUpTime }))), 'session')
175 | }
176 | }
177 | return startUpStatus
178 | }
179 |
180 | function checkBase () {
181 | for (var key in baseConfig.base) {
182 | resetCode()
183 | // baseConfig.status.FnName = 'AnalysysAgentInit'
184 | baseConfig.status.key = key
185 | var rule = fieldRules[key]
186 | if (key === '$debug') {
187 | rule = fieldRules.xcontext[key]
188 | }
189 | if (key === '$lib_version') {
190 | rule = fieldRules.xcontext[key]
191 | }
192 | var checkValue = rule
193 |
194 | if (checkValue && !checkFields(key, baseConfig.base[key], checkValue)) {
195 | baseConfig.base[key] = ''
196 | return false
197 | }
198 |
199 | successLog()
200 | }
201 | return true
202 | }
203 |
204 | function checkPrivate (obj, ruleName, isKey) {
205 | resetCode()
206 | var rule = fieldRules[ruleName] || fieldRules.xcontextCommonRule
207 | if (Util.paramType(obj) !== 'Object' || isKey === true) {
208 | var checkKey = rule.check.key
209 | var status = check(Util.trim(obj), checkKey)
210 | baseConfig.status.key = obj
211 | if (!status) {
212 | errorLog()
213 | return false
214 | }
215 | } else {
216 | for (var key in obj) {
217 | var valueStatus = checkFields(key, obj[key], rule)
218 | if (!valueStatus) {
219 | if (baseConfig.status.errorCode === '600019') {
220 | if (Util.paramType(obj[key]) === 'String' && obj[key].length > 500) {
221 | obj[key] = Util.stringSlice(obj[key], 499) + '$'
222 | }
223 | }
224 | }
225 | }
226 | }
227 | return true
228 | }
229 |
230 | export { fillField, clearCache, isStartUp, checkBase, checkPrivate, resetCode }
231 |
--------------------------------------------------------------------------------
/src/lib/fillField/sessionId.js:
--------------------------------------------------------------------------------
1 | import Storage from '../storage/index.js'
2 | import Util from '../common/index.js'
3 | import { clearUTM } from './UTM.js'
4 | function SessionId () {
5 | this.sessionId = Storage.getLocal('SEESIONID') || this.setId()
6 | this.sessionDate = Storage.getLocal('SEESIONDATE') || 0
7 | }
8 | SessionId.prototype.setId = function () {
9 | var date = +new Date()
10 | this.sessionId = Util.MD5('JS' + date.toString() + Math.random() * 10000000)
11 | this.sessionDate = date
12 | Storage.setLocal('SEESIONID', this.sessionId)
13 | Storage.setLocal('SEESIONDATE', this.sessionDate)
14 | return this.sessionId
15 | }
16 | SessionId.prototype.getId = function () {
17 | var date = new Date()
18 | var nowDate = date.getTime()
19 | var offsetGMT = date.getTimezoneOffset()
20 | var nowDay = new Date(nowDate + offsetGMT * 60 * 1000 + 8 * 60 * 60 * 1000).getDate()
21 | this.sessionDate = Storage.getLocal('SEESIONDATE') || 0
22 |
23 | var sessionDay = this.sessionDate === 0 ? 0 : new Date(this.sessionDate + offsetGMT * 60 * 1000 + 8 * 60 * 60 * 1000).getDate()
24 | if (!this.sessionId || !this.sessionDate || Number(nowDate) - Number(this.sessionDate) > 30 * 60 * 1000 || nowDay !== sessionDay) {
25 | clearUTM()
26 | this.setId()
27 | }
28 | this.sessionDate = nowDate
29 | Storage.setLocal('SEESIONDATE', nowDate)
30 | this.sessionId = Storage.getLocal('SEESIONID') || this.setId()
31 | return this.sessionId
32 | }
33 |
34 | export default new SessionId()
35 |
--------------------------------------------------------------------------------
/src/lib/fillField/spider.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 1.百度:Baiduspider Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)
3 | * 百度图片 Baiduspider-image+(+http://www.baidu.com/search/spider.htm)
4 | * 百度PC Mozilla/5.0 (compatible; Baiduspider-render/2.0; +http://www.baidu.com/search/spider.html
5 | * 百度移动端 Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1 (compatible; Baiduspider-render/2.0; +http://www.baidu.com/search/spider.html)
6 | *
7 | * 2.谷歌:Googlebot Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
8 | * Google图片 AdsBot-Google-Mobile (+http://www.google.com/mobile/adsbot.html) Mozilla (iPhone; U; CPU iPhone OS 3 0 like Mac OS X) AppleWebKit (KHTML, like Gecko) Mobile Safari
9 | * 3.360蜘蛛:360Spider 360搜索 Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0);
10 | * 360网站安全 360spider (http://webscan.360.cn)
11 | * 4.Bing爬虫: bingbot Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)
12 | * 5.腾讯搜搜蜘蛛:Sosospider Sosospider+(+http://help.soso.com/webspider.htm)
13 | * 搜搜图片 Sosoimagespider+(+http://help.soso.com/soso-image-spider.htm)
14 | * 6.雅虎蜘蛛:Yahoo! 雅虎英文 Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)
15 | * 雅虎中国 Mozilla/5.0 (compatible; Yahoo! Slurp China; http://misc.yahoo.com.cn/help.html)
16 | * 4.有道蜘蛛:YoudaoBot Mozilla/5.0 (compatible; YoudaoBot/1.0; http://www.youdao.com/help/webmaster/spider/; )
17 | * 8.搜狗蜘蛛:Sogou News Spider Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)
18 | * Sogou Pic Spider/3.0(+http://www.sogou.com/docs/help/webmasters.htm#07)
19 | * 9.瑞典 Speedy Spider: Speedy Spider Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) Speedy Spider (http://www.entireweb.com/about/search_tech/speedy_spider/)
20 | * 10.俄罗斯 yandex : YandexBot Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)
21 | * 11.MSN蜘蛛:msnbot/msnbot-media msnbot/1.1 (+http://search.msn.com/msnbot.htm)
22 | * 12.必应蜘蛛:bingbot/compatible Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)
23 | * 13.听云爬虫:networkbench Mozilla/5.0 (Windows NT 10.0; Trident/7.0; rv: 11.0;NetworkBench/8.0.1.309-5774440-2481662) like Gecko
24 | * 14.Alexa蜘蛛:ia_archiver ia_archiver/8.9 (Windows NT 3.1; en-US;)
25 | * 15.宜sou蜘蛛:EasouSpider Mozilla/5.0 (compatible; EasouSpider; +http://www.easou.com/search/spider.html)
26 | * 16.华为赛门铁克蜘蛛:HuaweiSymantecSpider HuaweiSymantecSpider/1.0+DSE-support@huaweisymantec.com+(compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR ; http://www.huaweisymantec.com/cn/IRL/spider)
27 | * 17.七牛镜像蜘蛛:qiniu qiniu-imgstg-spider-1.0
28 | * 18.DNSPod监控:DNSPod DNSPod-Monitor/2.0
29 | * 19.俄罗斯 LinkpadBot:LinkpadBot Mozilla/5.0 (compatible; LinkpadBot/1.06; +http://www.linkpad.ru)
30 | * 20.英国 MJ12bot:MJ12bot Mozilla/5.0 (compatible; MJ12bot/v1.4.0; http://www.majestic12.co.uk/bot.php?+)
31 | * 21.即刻蜘蛛:JikeSpider
32 | * 22.一淘网蜘蛛:EtaoSpider Mozilla/5.0 (compatible; EtaoSpider/1.0; EtaoSpider)
33 | * 23.人工智能爬虫:crawler Mozilla/5.0 (compatible; 008/0.83; http://www.80legs.com/webcrawler.html) Gecko/2008032620
34 | * 24.Scrapy爬虫: scrapy
35 | * 25.监控宝:jiankongbao Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; JianKongBao Monitor 1.1)
36 | * 26.OneAPM爬虫:OneAPM FFAgent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:39.0: OneAPM FFAgent)Gecko/20100101 Firefox/39.0
37 | * 27.PhantomJS:PhantomJS Mozilla/5.0 (Unknown; Linux x86_64)AppleWebKit/538. 1 (KHTML,like Gecko)PhantomJS/2.1.1 Safari/538.1
38 | * 28. BingPreview: Mozilla / 5.0 + (Windows + NT + 6.1; + WOW64) + AppleWebKit / 534++(KHTML, +like + Gecko) + BingPreview / 1.0 b
39 | */
40 | var UA = navigator.userAgent.toLowerCase()
41 |
42 | function checkSpider () {
43 | if (UA.match(/(bot|crawler|spider|scrapy|dnspod|ia_archiver|jiankongbao|slurp|transcoder|networkbench|oneapm|PhantomJS|BingPreview)/i)) {
44 | return true
45 | }
46 |
47 | return false
48 | }
49 |
50 | export {
51 | checkSpider
52 | }
53 |
--------------------------------------------------------------------------------
/src/lib/mergeRules/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 生产事件日志模板
3 | * commonTemp 为公用事件模板,用于自定义事件日志
4 | */
5 | import { fieldTemplate } from '../../configure/index.js'
6 | import Util from '../common/index.js'
7 | var eventTemp = {}
8 | var commonTemp = {}
9 | var baseTemp = fieldTemplate.base
10 | var outerTemp = baseTemp.outer
11 | for (var i = 0; i < outerTemp.length; i++) {
12 | if (baseTemp[outerTemp[i]]) {
13 | commonTemp[outerTemp[i]] = Util.toObj(baseTemp[outerTemp[i]])
14 | } else {
15 | commonTemp[outerTemp[i]] = ''
16 | }
17 | }
18 |
19 | for (var key in fieldTemplate) {
20 | if (key !== 'base') {
21 | var keyTemp = Util.toDeepObj(fieldTemplate[key])
22 | eventTemp[key + 'base'] = keyTemp
23 | eventTemp[key] = Util.objMerge(commonTemp, keyTemp)
24 | }
25 | }
26 |
27 | eventTemp.commonTemp = commonTemp
28 |
29 | function temp (eventName) {
30 | return eventTemp[eventName] || eventTemp.commonTemp
31 | }
32 |
33 | export { temp }
34 |
--------------------------------------------------------------------------------
/src/lib/printLog/index.js:
--------------------------------------------------------------------------------
1 | import baseConfig from '../baseConfig/index.js'
2 | import Util from '../common/index.js'
3 | import { lifecycle } from '../../configure/index.js'
4 | var errorMessage = {
5 | common: '{FN}:Property key invalid, nonsupport value: $lib/$lib_version/$platform/$first_visit_time/$debug/$is_login \n' +
6 | 'current KEY:{KEY}',
7 | 60001: '{FN}:Property key invalid, support type: String \n' +
8 | 'current key:{KEY}\n',
9 | 60002: '{FN}:Property value invalid of key[{KEY}], support type: Number \n' +
10 | 'current value:{VALUE}\n' +
11 | 'current type: {VALUETYPE}',
12 | 60003: '{FN}:Property value invalid of key[{KEY}], support type: Boolean \n' +
13 | 'current value:{VALUE}\n' +
14 | 'current type: {VALUETYPE}',
15 | 60004: '{FN}:Property value invalid of key[{KEY}], support type: Array \n' +
16 | 'current value:{VALUE}\n' +
17 | 'current type: {VALUETYPE}',
18 | 60005: '{FN}:The length of the property[{KEY}] value (string[{VALUE}]) needs to be 1-255 !',
19 | 60006: 'Please set appkey first.',
20 | 60007: 'Please set uploadURL first.',
21 | 60008: 'Send message failed.',
22 | 60009: '{FN}:The length of the property key (string[{KEY}]) needs to be 1-125 !',
23 | 600010: '{FN}:The length of the property key (string[{KEY}]) needs to be 1-99 !',
24 | 600011: '{FN}:[{KEY}] does not conform to naming rules!',
25 | 600012: '{FN}:Property key invalid, nonsupport value: $lib/$lib_version/$platform/$first_visit_time/$debug/$is_login \n' +
26 | 'current KEY:{KEY}',
27 | 600013: '{FN}:Property value invalid of key[{KEY}], support type: Array with String as its internal element \n' +
28 | 'current value:{VALUE}\n' +
29 | 'current type: {VALUETYPE}',
30 | 600016: '{FN}:Property value invalid of key[{KEY}], support type: Object \n' +
31 | 'current value:{VALUE}\n' +
32 | 'current type: {VALUETYPE}',
33 | 600017: '{FN}:The length of the property key (string[{KEY}]) needs to be 1-255 !',
34 | 600018: '{FN}:Property value invalid of key[{KEY}] invalid, support type: String \n' +
35 | 'current value:{VALUE}\n' +
36 | 'current type: {VALUETYPE}',
37 | 600019: '{FN}:The length of the property[{KEY}] value (string[{VALUE}]) needs to be 1-255 !',
38 | 600020: '{FN}:Property value invalid of key[{KEY}], support type: Boolean/Array/String/Number \n' +
39 | 'current value:{VALUE}\n' +
40 | 'current type: {VALUETYPE}'
41 | }
42 | var successMessage = {
43 | common: '',
44 | 20001: 'Send message success',
45 | 20002: '{FN}: set success ({VALUE})',
46 | 20003: '{FN}:({VALUE}) delete success',
47 | 20004: '{FN}:clear success',
48 | 20005: '{FN}:reset success',
49 | 20006: 'set appkey success. current appkey : {VALUE}',
50 | 20007: 'Init Analysys JS sdk success, version : {VALUE}',
51 | 20008: 'set uploadURL success. current uploadURL : {VALUE}',
52 | 20009: '{FN}:[{KEY}] : get failed',
53 | 20010: '{FN}:[{KEY}] : get success. ({VALUE})',
54 | 20011: '{FN}:({VALUE}) delete failed',
55 | 20013: 'aliasID already bound'
56 | }
57 |
58 | function successLog (msg) {
59 | if (baseConfig.base.$debug !== 1 && baseConfig.base.$debug !== 2) {
60 | return
61 | }
62 | var status = baseConfig.status
63 | var successCode = status.successCode
64 | var fn = status.FnName
65 | var key = status.key
66 | var value = status.value
67 | var msgTemp = successMessage[successCode] || successMessage.common
68 | if (Util.paramType(key) === 'String' && key.length > 30) {
69 | key = Util.stringSlice(key, 30) + '...'
70 | }
71 | if (Util.paramType(fn) === 'String' && fn.length > 30) {
72 | fn = Util.stringSlice(fn, 30) + '...'
73 | }
74 | var showMsg = msgTemp.replace('{FN}', fn)
75 | .replace('{KEY}', key)
76 | .replace('{VALUE}', value)
77 | if (msg) {
78 | showMsg = msg
79 | }
80 | if (!showMsg) return
81 |
82 | window.console && window.console.log && window.console.log(showMsg)
83 | }
84 |
85 | function errorLog () {
86 | if (baseConfig.base.$debug !== 1 && baseConfig.base.$debug !== 2) {
87 | return
88 | }
89 |
90 | var status = baseConfig.status
91 | var errorCode = status.errorCode
92 | var fn = status.FnName
93 | var key = status.key
94 | var value = status.value
95 | if (Util.paramType(value) === 'Object') {
96 | value = JSON.stringify(value)
97 | }
98 | var valueType = Util.paramType(value)
99 | if (errorCode === '600018' && !key) {
100 | errorCode = '600011'
101 | }
102 | if (errorCode === '60005' && !key) {
103 | errorCode = '600017'
104 | }
105 | if ((errorCode === '600017' || errorCode === '600019' || errorCode === '60009' || errorCode === '600010' || errorCode === '60005') && Util.paramType(value) === 'String' && value.length && value.length > 30) {
106 | value = Util.stringSlice(value, 30) + '...'
107 | }
108 | if (Util.paramType(key) === 'String' && key.length > 30) {
109 | key = Util.stringSlice(key, 30) + '...'
110 | }
111 | if (Util.paramType(fn) === 'String' && fn.length > 30) {
112 | fn = Util.stringSlice(fn, 30) + '...'
113 | }
114 | var msgTemp = errorMessage[errorCode] || errorMessage.common
115 | var showMsg = msgTemp.replace('{FN}', fn)
116 | .replace('{KEY}', key)
117 | .replace('{VALUE}', value)
118 | .replace('{VALUETYPE}', valueType)
119 |
120 | window.console && window.console.warn && window.console.warn(showMsg)
121 | if (lifecycle.errorLog && lifecycle.errorLog.init && errorCode !== '60008') {
122 | var FnName = baseConfig.status.FnName
123 | lifecycle.errorLog.init(showMsg)
124 | baseConfig.status.FnName = FnName
125 | }
126 | }
127 | export { errorLog, successLog }
128 |
--------------------------------------------------------------------------------
/src/lib/storage/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 存储模块。集中处理本地缓存内容
3 | * API:
4 | * Local相关:永久存储数据相关操作
5 | * session相关:临时存储数据相关操作
6 | *
7 | */
8 |
9 | import Util from '../common/index.js'
10 | import baseConfig from '../baseConfig/index.js'
11 |
12 |
13 | var Local = ''
14 | var Session = ''
15 | try {
16 | Local = typeof window.localStorage === 'object' ? window.localStorage : ''
17 | Session = typeof window.sessionStorage === 'object' ? window.sessionStorage : ''
18 | } catch (e) { }
19 |
20 | function Storage () {
21 | this.localName = 'FZ_STROAGE'
22 | this.sessionName = 'FZ_SESSION'
23 | this.cookieName = 'FZ_STROAGE' + '.' + Util.getDomainFromUrl(baseConfig.base.cross_subdomain)
24 | this.checkSubdomain()
25 | this.localObj = this.getLocal()
26 | this.sessionObj = this.getSession()
27 | }
28 | Storage.prototype.checkSubdomain = function () {
29 | var ans = window.AnalysysAgent || []
30 | if (Util.paramType(ans) === 'Array') {
31 | for (var i = 0; i < ans.length; i++) {
32 | if (ans[i][0] === 'cross_subdomain' && Util.paramType(ans[i][1]) === 'Boolean') {
33 | baseConfig.base.cross_subdomain = ans[i][1]
34 | }
35 | }
36 | }
37 | if (ans && Util.objHasKay(ans.config || {}, 'cross_subdomain')) {
38 | baseConfig.base.cross_subdomain = ans.config.cross_subdomain
39 | }
40 | if (baseConfig.base.cross_subdomain === true) {
41 | var cookieObj = this.getCookie(this.cookieName) || Util.encode('{}')
42 | cookieObj = JSON.parse(Util.decode(decodeURIComponent(cookieObj)))
43 | if (Util.paramType(cookieObj) === 'Object' && !Util.isEmptyObject(cookieObj)) {
44 | var cookieId = cookieObj['ARK_ID']
45 | var cookieSuper = {}
46 | if (Util.objHasKay(cookieObj, 'ARKSUPER') === true) {
47 | cookieSuper = cookieObj['ARKSUPER']
48 | delete cookieObj['ARKSUPER']
49 | }
50 | var mergeObj = Util.objMerge(this.localObj || {}, cookieObj)
51 | if (baseConfig.base.cross_subdomain_super === true && !Util.isEmptyObject(cookieSuper)) {
52 | mergeObj = Util.objMerge({ 'ARKSUPER': cookieSuper }, mergeObj)
53 | }
54 | this.setLocal(this.localName, mergeObj)
55 | this.setCookie('ARK_ID', cookieId)
56 | }
57 | }
58 | }
59 | Storage.prototype.setLocal = function (key, value) {
60 | this.localObj = this.getLocal()
61 | if (key === this.localName) {
62 | this.localObj = value
63 | } else {
64 | this.localObj[key] = value
65 | }
66 | try {
67 | if (!Local) {
68 | if (key !== 'POSTDATA') {
69 | this.setCookie(this.cookieName, encodeURIComponent(Util.encode(JSON.stringify(this.localObj))))
70 | }
71 | } else {
72 | Local.setItem(this.localName, Util.encode(JSON.stringify(this.localObj)))
73 | Session.setItem(this.localName, Util.encode(JSON.stringify(this.localObj)))
74 | }
75 | if (key !== 'POSTDATA' && baseConfig.base.cross_subdomain === true) {
76 | var saveLocalObj = Util.toDeep(this.localObj)
77 | delete saveLocalObj['POSTDATA']
78 | this.setCookie(this.cookieName, encodeURIComponent(Util.encode(JSON.stringify(saveLocalObj))))
79 | }
80 | } catch (e) { }
81 | }
82 |
83 | Storage.prototype.getLocal = function (key) {
84 | try {
85 | var localData = Util.encode('{}')
86 | if (!Local) {
87 | localData = this.getCookie(this.cookieName)
88 | if (localData) {
89 | localData = decodeURIComponent(localData)
90 | } else {
91 | localData = Util.encode(JSON.stringify(this.localObj))
92 | }
93 | } else {
94 | localData = Local.getItem(this.localName)
95 | if (!localData) {
96 | var sessionLocal = Session.getItem(this.localName)
97 | if (sessionLocal) {
98 | localData = Session.getItem(this.localName)
99 | Local.setItem(this.localName, localData)
100 | }
101 | }
102 | }
103 | this.localObj = JSON.parse(Util.decode(localData))
104 | if (!key) {
105 | return this.localObj
106 | }
107 | return this.localObj[key]
108 | } catch (e) {
109 | if (!key) {
110 | return {}
111 | } else {
112 | return ''
113 | }
114 | }
115 | }
116 |
117 | Storage.prototype.removeLocal = function (key) {
118 | this.localObj = this.getLocal()
119 | if (Util.objHasKay(this.localObj, key)) {
120 | delete this.localObj[key]
121 | }
122 |
123 | if (Util.isEmptyObject(this.localObj)) {
124 | try {
125 | if (Local) {
126 | Local.removeItem(this.localName)
127 | Session.removeItem(this.localName)
128 | }
129 | this.removeCookie(this.cookieName)
130 | } catch (e) { }
131 | } else {
132 | if (Local) {
133 | Local.setItem(this.localName, Util.encode(JSON.stringify(this.localObj)))
134 | Session.setItem(this.localName, Util.encode(JSON.stringify(this.localObj)))
135 | }
136 | if (key !== 'POSTDATA' && key !== 'ARK_ID' && baseConfig.base.cross_subdomain === true) {
137 | var saveLocalObj = Util.toDeep(this.localObj)
138 | delete saveLocalObj['POSTDATA']
139 | delete saveLocalObj['ARK_ID']
140 |
141 | this.setCookie(this.cookieName, Util.encode(JSON.stringify(saveLocalObj)))
142 | }
143 | }
144 | }
145 |
146 | Storage.prototype.setSession = function (key, value) {
147 | this.sessionObj = this.getSession()
148 | this.sessionObj[key] = value
149 | try {
150 | if (!Session) {
151 | if (key !== 'POSTDATA') {
152 | this.setCookie(this.sessionName, Util.encode(JSON.stringify(this.sessionObj)), 'session')
153 | }
154 | } else {
155 | Session.setItem(this.sessionName, Util.encode(JSON.stringify(this.sessionObj)))
156 | this.removeCookie(this.sessionName)
157 | }
158 | } catch (e) { }
159 | }
160 |
161 | Storage.prototype.getSession = function (key) {
162 | try {
163 | var sessionData = Util.encode('{}')
164 | if (!Session) {
165 | sessionData = this.getCookie(this.sessionName)
166 | if (!sessionData) {
167 | sessionData = Util.encode(JSON.stringify(this.sessionObj))
168 | }
169 | } else {
170 | sessionData = Session.getItem(this.sessionName) || Util.encode('{}')
171 | this.removeCookie(this.sessionName)
172 | }
173 | this.sessionObj = JSON.parse(Util.decode(sessionData))
174 |
175 | if (!key) {
176 | return this.sessionObj
177 | }
178 | return this.sessionObj[key]
179 | } catch (e) {
180 | return {}
181 | }
182 | }
183 |
184 | Storage.prototype.removeSession = function (key) {
185 | this.sessionObj = this.getSession()
186 | if (Util.objHasKay(this.sessionObj, key)) {
187 | delete this.sessionObj[key]
188 | }
189 |
190 | if (Util.isEmptyObject(this.sessionObj)) {
191 | try {
192 | if (!Session) {
193 | this.removeCookie(this.sessionName)
194 | } else {
195 | Session.removeItem(this.sessionName)
196 | this.removeCookie(this.sessionName)
197 | }
198 | } catch (e) { }
199 | } else {
200 | if (Session) {
201 | Session.setItem(this.sessionName, Util.encode(JSON.stringify(this.sessionObj)))
202 | }
203 | // if (key !== 'POSTDATA' && key !== 'ARK_ID') {
204 | // this.setCookie(this.sessionName, Util.encode(JSON.stringify(this.sessionObj)), 'session')
205 | // }
206 | }
207 | }
208 | Storage.prototype.setCookie = function (name, value, type) {
209 | // if (this.getCookie(name) && this.getCookie(name) !== value) {
210 | // this.removeCookie(name, !baseConfig.base.cross_subdomain, type)
211 | // }
212 | // this.removeCookie(name, baseConfig.base.cross_subdomain, type)
213 | var urlDomain = '.' + Util.getDomainFromUrl(baseConfig.base.cross_subdomain)
214 | var path = '; path=/'
215 | var domain = !urlDomain ? '' : ('; domain=' + urlDomain)
216 | var time = ''
217 | if (type !== 'session') {
218 | var date = new Date()
219 | date.setTime(date.getTime() + 1 * 365 * 24 * 60 * 60 * 1000)
220 | time = '; expires=' + date.toGMTString()
221 | }
222 | document.cookie = name + '=' + value + time + path + domain
223 | }
224 | Storage.prototype.getCookie = function (name) {
225 | name = name || this.localName
226 | var text = document.cookie
227 | if (typeof text !== 'string') {
228 | return ''
229 | }
230 | var nameEQ = name + '='
231 | var ca = text.split(/[;&]/)
232 | var i; var c
233 | for (i = 0; i < ca.length; i++) {
234 | c = ca[i]
235 | while (c.charAt(0) === ' ') {
236 | c = c.substring(1, c.length)
237 | }
238 | if (c.indexOf(nameEQ) === 0) {
239 | return c.substring(nameEQ.length, c.length) || ''
240 | }
241 | }
242 | }
243 | Storage.prototype.removeCookie = function (name, domainStatus, type) {
244 | domainStatus = Util.paramType(domainStatus) === 'Boolean' ? domainStatus : baseConfig.base.cross_subdomain
245 | var urlDomain = '.' + Util.getDomainFromUrl(domainStatus)
246 | var path = '; path=/'
247 | var domain = !urlDomain ? '' : ('; domain=' + urlDomain)
248 | if (type !== 'session') {
249 | var date = new Date()
250 | date.setTime(date.getTime() - 3 * 365 * 24 * 60 * 60 * 1000)
251 | var time = '; expires=' + date.toGMTString()
252 | }
253 | document.cookie = name + '=' + time + path + domain
254 | }
255 |
256 |
257 | export default new Storage()
258 |
--------------------------------------------------------------------------------
/src/lib/upload/ajax.js:
--------------------------------------------------------------------------------
1 | import Storage from '../storage/index.js'
2 | import Util from '../common/index.js'
3 | import baseConfig from '../baseConfig/index.js'
4 |
5 | function getJSON (data) {
6 | if (Util.paramType(data) === 'String') {
7 | if (data.indexOf('\n') > -1) {
8 | data = data.replace(/[\r\n]/g, '')
9 | }
10 |
11 | try {
12 | return JSON.parse(data)
13 | } catch (e) { }
14 | try {
15 | return window.AnalysysModule.zipInflate(data)
16 | } catch (e) { }
17 | if (data === 'H4sIAAAAAAAAAKtWSs5PSVWyMjIwqAUAVAOW6gwAAAA=') {
18 | return {
19 | code: 200
20 | }
21 | } else if (data === 'H4sIAAAAAAAAAKtWSs5PSVWyMjUwqAUA7TtBdwwAAAA=') {
22 | return {
23 | code: 500
24 | }
25 | } else if (data === 'H4sIAAAAAAAAAKtWSs5PSVWyMjEy0FHKLU5XslJySSxJVHBJTS6qLChRcC0qyi/S01OqBQBdATGSKQAAAA==') {
26 | return {
27 | code: 420
28 | }
29 | }
30 | return {
31 | code: 200
32 | }
33 | } else if (Util.paramType(data) === 'Object') {
34 | return data
35 | } else {
36 | return {
37 | code: 200
38 | }
39 | }
40 | }
41 |
42 | function GetHttpObj () {
43 | var httpobj = null
44 | if (window.XDomainRequest) {
45 | return new window.XDomainRequest()
46 | }
47 | if (window.XMLHttpRequest) {
48 | httpobj = new window.XMLHttpRequest()
49 | } else {
50 | try {
51 | httpobj = new window.ActiveXObject('Microsoft.XMLHTTP')
52 | } catch (e) {
53 | try {
54 | httpobj = new window.ActiveXObject('Msxml2.XMLHTTP')
55 | } catch (e1) {
56 | httpobj = new window.XMLHttpRequest()
57 | }
58 | }
59 | }
60 | return httpobj
61 | }
62 |
63 | function xmlhttp (_this) {
64 | var sendStatus = false
65 | var xhr = new GetHttpObj()
66 | // xhr.setRequestHeader("reqt",+new Date())
67 | // xhr.setRequestHeader("reqv",1)
68 | xhr.onload = function () {
69 | if (sendStatus) return
70 | sendStatus = true
71 | _this.success(getJSON(xhr.responseText), xhr)
72 | }
73 | xhr.onerror = function () {
74 | if (sendStatus) return
75 | sendStatus = true
76 | _this.error(getJSON(xhr.responseText), xhr)
77 | }
78 | xhr.onreadystatechange = (function (xhr, _this) {
79 | return function () {
80 | if (xhr.readyState === 4) {
81 | try {
82 | if (xhr.getAllResponseHeaders().indexOf('Date') > -1 || xhr.getAllResponseHeaders().indexOf('date') > -1) {
83 | var time = +new Date()
84 | var date = xhr.getResponseHeader('Date') || xhr.getResponseHeader('date')
85 | if (date && baseConfig.base.allowTimeCheck === true) {
86 | Storage.setLocal('ANSSERVERTIME', +new Date(date) - time)
87 | } else {
88 | Storage.setLocal('ANSSERVERTIME', 0)
89 | }
90 | }
91 | } catch (e) { }
92 |
93 | if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
94 | if (sendStatus) return
95 | sendStatus = true
96 | _this.success(getJSON(xhr.responseText), xhr)
97 | } else {
98 | if (sendStatus) return
99 | sendStatus = true
100 | _this.error()
101 | }
102 | xhr.onreadystatechange = null
103 | xhr.onload = null
104 | }
105 | }
106 | })(xhr, _this)
107 | try {
108 | xhr.open(_this.type, _this.url, true)
109 | // xhr.setRequestHeader("Content-Type","multipart/form-data")
110 | try {
111 | xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
112 | } catch (e) { }
113 | var timeNum = baseConfig.base.sendDataTimeout
114 | if (_this.type === 'GET') {
115 | timeNum = baseConfig.base.getDataTimeout
116 | xhr.send(null)
117 | } else {
118 | xhr.send(_this.data)
119 | }
120 |
121 | if (Util.paramType(timeNum) === 'Number') {
122 | if (Util.paramType(xhr.timeout) === 'Number') {
123 | xhr.timeout = timeNum
124 | } else {
125 | var timeCallback = (function (xhr) {
126 | return function () {
127 | xhr.abort()
128 | }
129 | })(xhr)
130 | setTimeout(timeCallback, timeNum)
131 | }
132 |
133 | }
134 | } catch (e) {
135 | }
136 | }
137 |
138 | // function lengthBaty(str) {
139 | // var bytesCount = 0
140 | // for (var i = 0; i < str.length; i++) {
141 | // var c = str.charAt(i)
142 | // if (/^[\u0000-\u00ff]$/.test(c)) //匹配双字节
143 | // {
144 | // bytesCount += 1
145 | // } else {
146 | // bytesCount += 2
147 | // }
148 | // }
149 | // return bytesCount
150 | // }
151 |
152 | function ajax () {
153 | this.url = ''
154 | this.data = ''
155 | this.type = 'GET'
156 | this.success = function () { }
157 | this.error = function () { }
158 | }
159 | ajax.prototype.get = function (option) {
160 | var param = []
161 | for (var key in option.data) {
162 | param.push(key + '=' + encodeURIComponent(option.data[key]))
163 | }
164 | var url = option.url.indexOf('?') > -1 ? (option.url + '&' + param.join('&')) : (option.url + '?' + param.join('&'))
165 | this.url = url
166 | this.data = option.data
167 | this.type = 'GET'
168 | this.success = option.success || function () { }
169 | this.error = option.error || function () { }
170 | xmlhttp(this)
171 | }
172 | ajax.prototype.post = function (option) {
173 | this.url = option.url
174 | this.data = option.data
175 | this.type = 'POST'
176 | this.success = option.success || function () { }
177 | this.error = option.error || function () { }
178 | xmlhttp(this)
179 | }
180 | export default ajax
181 |
--------------------------------------------------------------------------------
/src/lib/upload/hybrid.js:
--------------------------------------------------------------------------------
1 | import Util from '../common/index.js'
2 | import { successLog } from '../printLog/index.js'
3 | function loadIframeUrl (url, callback) {
4 | if (!document.body) {
5 | setTimeout(function () { loadIframeUrl(url, callback) }, 200)
6 | return
7 | }
8 | var iframe = document.createElement('iframe')
9 | iframe.setAttribute('src', url)
10 | iframe.setAttribute('id', 'AnalysysAgentIframe')
11 | iframe.setAttribute('style', 'display:none;')
12 |
13 | document.body.appendChild(iframe)
14 | iframe.parentNode.removeChild(iframe)
15 | }
16 |
17 | function transporter (funName, paramArray, callbackFunName, callback) {
18 | var params = {
19 | functionName: funName,
20 | functionParams: paramArray
21 | }
22 | if (Util.paramType(callbackFunName) === 'String') {
23 | params.callbackFunName = callbackFunName
24 | } else if (Util.paramType(callbackFunName) === 'Function') {
25 | callback = callbackFunName
26 | }
27 | var msg = JSON.stringify(params)
28 | successLog('Send message to app: \ndata:' + msg)
29 | if (window.AnalysysModule && window.AnalysysModule.moduleStatus === true) {
30 | window.AnalysysModule.upData(params)
31 | } else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.AnalysysAgent) {
32 | postMessage(params)
33 | } else if (window.AnalysysAgentHybrid && window.AnalysysAgentHybrid.analysysHybridCallNative) {
34 | callNative(msg)
35 | } else {
36 | var url = 'analysysagent:' + msg
37 | loadIframeUrl(url)
38 | }
39 | if (Util.paramType(callback) === 'Function') {
40 | callback.call(callback)
41 | }
42 | }
43 |
44 | function backParamsArray () {
45 | var arg = arguments
46 | var argArray = []
47 | var callback = null
48 | for (var i = 0; i < arg.length; i++) {
49 | if (arg[i] !== undefined) {
50 | if (Util.paramType(arg[i]) === 'Object') {
51 | for (var key in arg[i]) {
52 | if (Util.paramType(arg[i][key]) === 'Function') {
53 | arg[i][key] = arg[i][key].call(arg[i][key])
54 | }
55 | }
56 | }
57 | if (Util.paramType(arg[i]) === 'Function') {
58 | callback = arg[i]
59 | } else {
60 | argArray.push(arg[i])
61 | }
62 | }
63 | }
64 | return {
65 | argArray: argArray,
66 | callback: callback
67 | }
68 | }
69 |
70 | function postMessage (obj) {
71 | window.webkit.messageHandlers.AnalysysAgent.postMessage(obj)
72 | }
73 | function callNative (msg) {
74 | window.AnalysysAgentHybrid.analysysHybridCallNative(msg)
75 | }
76 | export { transporter, backParamsArray }
--------------------------------------------------------------------------------
/src/lib/upload/index.js:
--------------------------------------------------------------------------------
1 | import Util from '../common/index.js'
2 | import LogAjax from './ajax.js'
3 | import Storage from '../storage/index.js'
4 | import baseConfig from '../baseConfig/index.js'
5 | import { errorLog, successLog } from '../printLog/index.js'
6 | import { lifecycle } from '../../configure/index.js'
7 |
8 | var postStatus = true
9 | var sendType = 'img'
10 | var rxDangerous = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g
11 |
12 | function delRx (list) {
13 | if (Util.paramType(list) === 'Array') {
14 | for (var i = 0; i < list.length; i++) {
15 | list[i] = delRx(list[i])
16 | }
17 | }
18 | if (Util.paramType(list) === 'Object') {
19 | for (var key in list) {
20 | var value = list[key]
21 | list[key] = delRx(value)
22 | }
23 | }
24 | if (Util.paramType(list) === 'String') {
25 | var rplist = list.replace(rxDangerous, function (a) {
26 | return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4)
27 | })
28 | if (Util.paramType(rplist) !== 'Sting') {
29 | return list
30 | } else {
31 | return rplist
32 | }
33 | }
34 | return list
35 | }
36 |
37 | function sendPost (data, callback) {
38 | if (Util.GetUrlParam('visual') && Util.GetUrlParam('visual').indexOf('true') > -1) {
39 | return
40 | }
41 | if (sendType !== 'img') {
42 | postStatus = false
43 | }
44 |
45 | var msg = data
46 | if (Util.paramType(data) === 'Array') {
47 | data = delRx(data)
48 | msg = JSON.stringify(data)
49 | }
50 | if (window.AnalysysModal && typeof (window.AnalysysModal) === 'function') {
51 | window.AnalysysModal(data)
52 | }
53 | // 发送日志发送失败,进入缓存序列
54 | var error = function () {
55 | postStatus = true
56 | baseConfig.status.errorCode = '60008'
57 | errorLog()
58 | Util.paramType(callback) === 'Function' && callback.call(callback)
59 | }
60 | // 发送成功后,将缓存序列对应数据去除
61 | var successCheckPost = function (data) {
62 | postStatus = true
63 |
64 | var postDataList = Storage.getLocal('POSTDATA') || []
65 | if (Util.isEmptyObject(postDataList)) {
66 | postDataList = []
67 | Storage.removeLocal('POSTDATA')
68 | }
69 | if (postDataList.length === 0) {
70 | Storage.removeLocal('POSTDATA')
71 | return
72 | }
73 | var saveData = []
74 | for (var i = 0; i < postDataList.length; i++) {
75 | var delData = false
76 | for (var y = 0; y < data.length; y++) {
77 | if (data[y].xwhen === postDataList[i].xwhen || !data[y].xwhen || !postDataList[i].xwhen) {
78 | delData = true
79 | }
80 | }
81 | if (delData === false && Util.paramType(postDataList[i]) === 'Object' && !Util.isEmptyObject(postDataList[i])) {
82 | saveData.push(postDataList[i])
83 | }
84 | }
85 | if (saveData.length > 0 && sendType !== 'img') {
86 | Storage.setLocal('POSTDATA', saveData)
87 | sendPost(saveData)
88 | } else {
89 | Storage.removeLocal('POSTDATA')
90 | }
91 | }
92 | // 发送成功执行
93 | var success = (function (data) {
94 | return function (msg) {
95 | if (msg.code === 200 || msg.code === 400 || msg.code === 4200) {
96 | baseConfig.status.successCode = '20001'
97 | successLog()
98 | successCheckPost(data)
99 | if (Util.paramType(callback) === 'Function') {
100 | callback.call(callback)
101 | }
102 | } else {
103 | error()
104 | }
105 | }
106 | })(data)
107 | var url = baseConfig.base.uploadURL + 'up?appid=' + baseConfig.base.appid
108 | var postMsg = {
109 | url: url,
110 | data: msg,
111 | success: success,
112 | error: error
113 | }
114 | successLog('Send message to server: ' + baseConfig.base.uploadURL + 'up?appid=' + baseConfig.base.appid + '\ndata:' + msg)
115 | if (lifecycle.upload && lifecycle.upload.init) {
116 | postMsg = lifecycle.upload.init(postMsg)
117 | } else if (window.AnalysysModule && Util.paramType(window.AnalysysModule) === 'Object' && Util.paramType(window.AnalysysModule.uploadData) === 'Function') {
118 | window.AnalysysModule.encryptInit(baseConfig.base)
119 | postMsg = window.AnalysysModule.uploadData(postMsg)
120 | }
121 | // if (sendType === 'get') {
122 | // snedGet(postMsg)
123 | // return
124 | // }
125 | if (sendType === 'img') {
126 | snedGet(postMsg, 'img')
127 | return
128 | }
129 | if (sendType === 'post') {
130 | new LogAjax().post(postMsg)
131 | return
132 | }
133 | if (sendType === 'send') {
134 | snedGet(postMsg, 'send')
135 | return
136 | }
137 | new LogAjax().post(postMsg)
138 | }
139 |
140 | function setValidKey (option) {
141 | var data = {
142 | data: option.data,
143 | send_type: ''
144 | }
145 | var param = []
146 | for (var key in data) {
147 | param.push(key + '=' + encodeURIComponent(data[key]))
148 | }
149 | var validurl = option.url.indexOf('?') > -1 ? (option.url + '&' + param.join('&')) : (option.url + '?' + param.join('&'))
150 |
151 | validurl = validurl.replace(baseConfig.base.uploadURL, '/')
152 |
153 | var validValue = Util.MD5(validurl, 32).split('')
154 | var validkey = validValue[2] + '' + validValue[0] + '' + validValue[4]
155 | data.send_type = validkey
156 | return data
157 | }
158 |
159 | function snedGet (option, type) {
160 | if (type === 'send' && navigator.sendBeacon) {
161 | var sendStatus = navigator.sendBeacon(option.url, option.data)
162 | if (sendStatus) {
163 | option.success({
164 | code: 200
165 | })
166 | }
167 | return
168 | }
169 | if (type === 'send' && !navigator.sendBeacon) {
170 | type = 'img'
171 | }
172 | option.data = Util.encode(option.data)
173 | option.data = setValidKey(option)
174 | // option.data = {
175 | // data: option.data,
176 | // send_type: validkey
177 | // }
178 | if (type === 'img') {
179 | var param = []
180 | for (var key in option.data) {
181 | param.push(key + '=' + encodeURIComponent(option.data[key]))
182 | }
183 | var url = option.url.indexOf('?') > -1 ? (option.url + '&' + param.join('&')) : (option.url + '?' + param.join('&'))
184 |
185 | var dom = document
186 | var createImg = dom.createElement('img')
187 | var sendTimer = null
188 | createImg.width = 1
189 | createImg.height = 1
190 | createImg.onerror = createImg.onload = function () {
191 | clearTimeout(sendTimer)
192 | option.success({ code: 200 })
193 | this.src = ''
194 | this.onload = null
195 | this.onerror = null
196 | this.onabort = null
197 | }
198 | createImg.onabort = function () {
199 | this.src = ''
200 | this.onload = null
201 | this.onerror = null
202 | this.onabort = null
203 | option.error()
204 | }
205 | if (Util.paramType(baseConfig.base.sendDataTimeout) === 'Number') {
206 | sendTimer = setTimeout(function () {
207 | createImg.onabort()
208 | }, baseConfig.base.sendDataTimeout)
209 | }
210 | createImg.src = url
211 | }
212 | }
213 |
214 | function checkLogBaseJson (obj) {
215 | if (Util.paramType(obj) === 'Object' && !Util.isEmptyObject(obj)) {
216 | var status = true
217 | for (var i = 0; i < baseConfig.baseJson.length; i++) {
218 | var key = baseConfig.baseJson[i]
219 | if (key === 'xwhat') {
220 | continue
221 | }
222 | if (!obj[key] || (Util.paramType(obj[key]) === 'Object' && Util.isEmptyObject(obj[key]))) {
223 | status = false
224 | }
225 | }
226 | return status
227 | }
228 | return false
229 | }
230 |
231 | function checkSavaData (list) {
232 | var dataList = []
233 | if (Util.paramType(list) === 'Array' && list.length > 0) {
234 | for (var i = 0; i < list.length; i++) {
235 | var itemList = checkSavaData(list[i])
236 | if (itemList.length > 0) {
237 | dataList.push.apply(dataList, itemList)
238 | }
239 | }
240 | }
241 | if (Util.paramType(list) === 'Object' && !Util.isEmptyObject(list) &&
242 | checkLogBaseJson(list)) {
243 | dataList.push(list)
244 | }
245 | return dataList
246 | }
247 |
248 | function upLog (log, callback) {
249 | try {
250 | if (baseConfig.base.sendType) {
251 | sendType = baseConfig.base.sendType
252 | }
253 | if (baseConfig.base.uploadURL.charAt(baseConfig.base.uploadURL.length - 1) !== '/') {
254 | baseConfig.base.uploadURL += '/'
255 | }
256 |
257 | var upData = []
258 | if (sendType === 'img') {
259 | upData = checkSavaData(log)
260 | } else {
261 | var postDataList = Storage.getLocal('POSTDATA') || []
262 | postDataList = checkSavaData(postDataList)
263 |
264 | if (postDataList.length === 0) {
265 | Storage.removeLocal('POSTDATA')
266 | }
267 | upData = postDataList
268 | if (postDataList.length < 500) {
269 | upData.push.apply(upData, checkSavaData(log))
270 | } else {
271 | upData = checkSavaData(log)
272 | }
273 | Storage.setLocal('POSTDATA', upData)
274 | }
275 |
276 | if (postStatus === false && sendType !== 'img') {
277 | Util.paramType(callback) === 'Function' && callback.call(callback)
278 | return
279 | }
280 | if (upData.length > 0) {
281 | if (sendType === 'img') {
282 | for (var i = 0; i < upData.length; i++) {
283 | if (i === 0) {
284 | sendPost([upData[i]], callback)
285 | } else {
286 | sendPost([upData[i]])
287 | }
288 | }
289 | } else {
290 | sendPost(upData, callback)
291 | }
292 | }
293 | } catch (e) {
294 | }
295 | }
296 |
297 | export { upLog }
298 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 发布API
3 | */
4 | import './lib/compatible/JSON2.js'
5 | import * as ans from './API/index.js'
6 | import Util from './lib/common/index.js'
7 | import baseConfig from './lib/baseConfig/index.js'
8 | import * as getField from './lib/fillField/getField.js'
9 | import { lifecycle } from './configure/index.js'
10 | import { startUp } from './API/template/startUp.js'
11 | import { clearCache } from './lib/fillField/index.js'
12 | import { ieCreat } from './lib/compatible/index.js'
13 | import { HybridAns } from './configure/customized/hybrid/lib/hybrid'
14 | window.AnalysysAgent = window.AnalysysAgent || {}
15 | var AnalysysAgent = window.AnalysysAgent
16 | var AnalysysModule = window.AnalysysModule || {}
17 | var config = AnalysysAgent.config || {}
18 | var param = AnalysysAgent.param || []
19 | if (AnalysysAgent.isInit !== true) {
20 | for (var key in ans) {
21 | AnalysysAgent[key] = (function (key) {
22 | return function () {
23 | var _arguments = arguments
24 | if (key.indexOf('get') > -1) {
25 | return ans[key].apply(ans[key], _arguments)
26 | }
27 | param.push([key, arguments])
28 | }
29 | })(key)
30 | }
31 | }
32 | function isHybrid () {
33 | if (window.navigator.userAgent.indexOf('AnalysysAgent/Hybrid') > -1
34 | ) {
35 | baseConfig.base.isHybrid = true
36 | }
37 | if (window.AnalysysAgentHybrid && window.AnalysysAgentHybrid.isHybrid() === true) {
38 | baseConfig.base.isHybrid = true
39 | }
40 | if (AnalysysModule && AnalysysModule.moduleStatus === true) {
41 | AnalysysModule.isHybrid()
42 | return
43 | }
44 | }
45 | ieCreat() //ie兼容
46 | isHybrid() //Hybrid模式检测
47 | function _createAnsSDK () {
48 | AnalysysAgent.isInit = true
49 | for (var key in ans) {
50 | AnalysysAgent[key] = ans[key]
51 | }
52 | for (var configKey in config) {
53 | if (Util.paramType(getField[configKey]) === 'Function') {
54 | getField[configKey](config[configKey])
55 | } else {
56 | baseConfig.base[configKey] = config[configKey]
57 | }
58 | }
59 | if (baseConfig.base.isHybrid === true) {
60 | for (var hybridKey in HybridAns) {
61 | AnalysysAgent[hybridKey] = AnalysysModule.moduleStatus === true ? AnalysysModule.onEvent(hybridKey, HybridAns) : HybridAns[hybridKey]
62 | }
63 | }
64 | AnalysysAgent.config = baseConfig.base
65 | // AnalysysAgent.config.setDebugModel = getField.debugMode
66 | // baseConfig.base = AnalysysAgent.config
67 |
68 | clearCache()
69 | for (var y = 0; y < param.length; y++) {
70 | var yItem = param[y]
71 | if (Util.objHasKay(ans, yItem[0]) && (yItem[0] === 'identify' || yItem[0] === 'alias' || yItem[0].indexOf('Super') > -1)) {
72 | ans[yItem[0]].apply(ans[yItem[0]], yItem[1])
73 | }
74 | }
75 | if (lifecycle.AnalysysAgent && lifecycle.AnalysysAgent.init) {
76 | lifecycle.AnalysysAgent.init(baseConfig.base)
77 | }
78 | // 如存在修改则重置登录及启动状态
79 | startUp()
80 | for (var z = 0; z < param.length; z++) {
81 | var zItem = param[z]
82 | if (Util.objHasKay(ans, zItem[0]) && zItem[0] !== 'identify' && zItem[0] !== 'alias' && zItem[0].indexOf('Super') < 0) {
83 | ans[zItem[0]].apply(ans[zItem[0]], zItem[1])
84 | }
85 | }
86 | }
87 |
88 | AnalysysAgent.init = function (conf) {
89 | if (Util.paramType(config) === 'Object' && (!AnalysysAgent.isInit || baseConfig.base.isHybrid === true) && (!AnalysysModule.moduleStatus || AnalysysModule.moduleStatus === true && (conf.isHybrid === true || conf.isARKH5 === true))) {
90 | if (conf.isARKH5 !== true) {
91 | config = conf
92 | }
93 | _createAnsSDK()
94 | }
95 | }
96 | if (!AnalysysAgent.isInit) {
97 | if (Util.paramType(AnalysysAgent) === 'Array') {
98 |
99 | for (var i = 0; i < AnalysysAgent.length; i++) {
100 | if (Util.paramType(ans[AnalysysAgent[i][0]]) === 'Function') {
101 | var fnName = AnalysysAgent[i][0]
102 | AnalysysAgent[i].splice(0, 1)
103 | param.push([fnName, AnalysysAgent[i]])
104 | } else {
105 | config[AnalysysAgent[i][0]] = AnalysysAgent[i][1]
106 | }
107 | }
108 | }
109 | if (Util.isEmptyObject(config) === false && !AnalysysModule.moduleStatus) {
110 | _createAnsSDK()
111 | }
112 | }
113 |
114 | export default AnalysysAgent
--------------------------------------------------------------------------------
/vue-demo/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw?
22 |
23 | *.lock
--------------------------------------------------------------------------------
/vue-demo/README.md:
--------------------------------------------------------------------------------
1 | # vue-demo
2 |
3 | ## Project setup
4 | ```
5 | npm install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | npm run serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | npm run build
16 | ```
17 |
18 | ### Lints and fixes files
19 | ```
20 | npm run lint
21 | ```
22 |
23 | ### Customize configuration
24 | See [Configuration Reference](https://cli.vuejs.org/config/).
25 |
--------------------------------------------------------------------------------
/vue-demo/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/vue-demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-demo",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "core-js": "^3.3.2",
12 | "element-ui": "^2.13.0",
13 | "vue": "^2.6.10",
14 | "vue-router": "^3.1.3"
15 | },
16 | "devDependencies": {
17 | "@vue/cli-plugin-babel": "^4.0.0",
18 | "@vue/cli-plugin-eslint": "^4.0.0",
19 | "@vue/cli-service": "^4.0.0",
20 | "babel-eslint": "^10.0.3",
21 | "eslint": "^5.16.0",
22 | "eslint-plugin-vue": "^5.0.0",
23 | "vue-template-compiler": "^2.6.10"
24 | },
25 | "eslintConfig": {
26 | "root": true,
27 | "env": {
28 | "node": true
29 | },
30 | "extends": [
31 | "plugin:vue/essential"
32 | ],
33 | "rules": {
34 | "indent": [
35 | 1,
36 | 4
37 | ]
38 | },
39 | "parserOptions": {
40 | "parser": "babel-eslint"
41 | }
42 | },
43 | "postcss": {
44 | "plugins": {
45 | "autoprefixer": {}
46 | }
47 | },
48 | "browserslist": [
49 | "> 1%",
50 | "last 2 versions"
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/vue-demo/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analysys/ans-javascript-sdk/83a214c8c92f79557107d105c67223b7c32632ee/vue-demo/public/favicon.ico
--------------------------------------------------------------------------------
/vue-demo/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | vue-demo
9 |
10 |
11 |
12 | We're sorry but vue-demo doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/vue-demo/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | JS SDK 接入Demo
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
27 |
28 |
64 |
--------------------------------------------------------------------------------
/vue-demo/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/analysys/ans-javascript-sdk/83a214c8c92f79557107d105c67223b7c32632ee/vue-demo/src/assets/logo.png
--------------------------------------------------------------------------------
/vue-demo/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import VueRouter from 'vue-router'
4 | import routes from './routes/index'
5 | import ElementUI from 'element-ui';
6 | import 'element-ui/lib/theme-chalk/index.css';
7 | import AnalysysAgent from "./sdk/AnalysysAgent_JS_SDK.es6.min.js";
8 |
9 | import "./sdk/AnalysysAgent_GBK.es6.min.js";
10 | import "./sdk/AnalysysAgent_Encrypt.es6.min.js";
11 | import "./sdk/AnalysysAgent_PageViewStayTime.es6.min.js";
12 |
13 | import "./sdk/AnalysysAgent_ExposurePoint.es6.min.js";
14 |
15 | AnalysysAgent.init({
16 | appkey: "commondebug", //APPKEY
17 | debugMode: 2,
18 | uploadURL: "https://sdk.analysys.cn:4089/",
19 | visitorConfigURL: "https://sdk.analysys.cn:4089/",
20 | SDKFileDirectory: "./js/sdk/",
21 | encryptType: 2,
22 | exposure: {
23 | valid_time: 300,//停留有效时间
24 | property: {
25 | cc: function () {
26 | return +new Date()
27 | }
28 | },//自定义参数
29 | exposure_click: true, // 是否自动采集曝光元素点击事件
30 | multiple: 5000,//true或毫秒值, 是否重复采集曝光点数据或多少毫秒后可再次采集
31 | element_list: function () {
32 | var list = [].slice.call(document.getElementsByTagName('a'), 0)
33 | var spanList = [].slice.call(document.getElementsByTagName('span'), 0)
34 | list.push.apply(list, spanList)
35 | return list
36 | }
37 | }
38 | /**如无自定义配置,则与uploadURL相同**/
39 | });
40 | Vue.config.productionTip = false
41 | Vue.prototype.AnalysysAgent = AnalysysAgent
42 | Vue.use(VueRouter)
43 | Vue.use(ElementUI)
44 | const router = new VueRouter({
45 | routes // (缩写) 相当于 routes: routes
46 | })
47 | new Vue({
48 | router,
49 | render: h => h(App)
50 | }).$mount('#app')
--------------------------------------------------------------------------------
/vue-demo/src/routes/index.js:
--------------------------------------------------------------------------------
1 | import Index from '../components/index.vue'
2 | import Next from '../components/next.vue'
3 | const routes = [{
4 | path: '/',
5 | component: Index
6 | },
7 | {
8 | path: '/next',
9 | component: Next
10 | }
11 | ]
12 | export default routes
--------------------------------------------------------------------------------
/vue-demo/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | publicPath: './'
3 | }
--------------------------------------------------------------------------------