-
-
Notifications
You must be signed in to change notification settings - Fork 246
/
Copy pathpage.js
106 lines (96 loc) · 2.66 KB
/
page.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Page View Reducer. Follows ducks pattern http://bit.ly/2DnERMc
import { isBrowser } from '@analytics/type-utils'
import serialize from '../utils/serialize'
import EVENTS from '../events'
const hashRegex = /#.*$/
function canonicalUrl() {
if (!isBrowser) return
const tags = document.getElementsByTagName('link')
for (var i = 0, tag; tag = tags[i]; i++) {
if (tag.getAttribute('rel') === 'canonical') {
return tag.getAttribute('href')
}
}
}
function urlPath(url) {
const regex = /(http[s]?:\/\/)?([^\/\s]+\/)(.*)/g
const matches = regex.exec(url)
const pathMatch = (matches && matches[3]) ? matches[3].split('?')[0].replace(hashRegex, '') : ''
return '/' + pathMatch
}
/**
* Return the canonical URL and rmove the hash.
* @param {string} search - search param
* @return {string} return current canonical URL
*/
function currentUrl(search) {
const canonical = canonicalUrl()
if (!canonical) return window.location.href.replace(hashRegex, '')
return canonical.match(/\?/) ? canonical : canonical + search
}
/**
* Page data for overides
* @typedef {object} PageData
* @property {string} [title] - Page title
* @property {string} [url] - Page url
* @property {string} [path] - Page path
* @property {string} [search] - Page search
* @property {string} [width] - Page width
* @property {string} [height] - Page height
*/
/**
* Get information about current page
* @typedef {Function} getPageData
* @param {PageData} [pageData = {}] - Page data overides
* @return {PageData} resolved page data
*/
export const getPageData = (pageData = {}) => {
if (!isBrowser) return pageData
const { title, referrer } = document
const { location, innerWidth, innerHeight } = window
const { hash, search } = location
const url = currentUrl(search)
const page = {
title: title,
url: url,
path: urlPath(url),
hash: hash,
search: search,
width: innerWidth,
height: innerHeight,
}
if (referrer && referrer !== '') {
page.referrer = referrer
}
return {
...page,
/* .page() user overrrides */
...pageData
}
}
const initialState = {
last: {},
history: [],
}
// page reducer
export default function page(state = initialState, action) {
const { properties, options, meta } = action
switch (action.type) {
case EVENTS.page:
const viewData = serialize({
properties,
meta,
...(Object.keys(options).length) && { options: options },
})
return {
...state,
...{
last: viewData,
// Todo prevent LARGE arrays https://bit.ly/2MnBwPT
history: state.history.concat(viewData)
}
}
default:
return state
}
}