Resume the pv cache source & add validation for the number of localStorage keys
This commit is contained in:
parent
a03149cd40
commit
aa54e901b1
2 changed files with 88 additions and 48 deletions
|
@ -18,30 +18,42 @@ const getInitStatus = (function () {
|
||||||
}());
|
}());
|
||||||
|
|
||||||
const PvOpts = (function () {
|
const PvOpts = (function () {
|
||||||
|
function getContent(selector) {
|
||||||
|
return $(selector).attr("content");
|
||||||
|
}
|
||||||
|
|
||||||
function hasContent(selector) {
|
function hasContent(selector) {
|
||||||
let content = $(selector).attr("content");
|
let content = getContent(selector);
|
||||||
return (typeof content !== "undefined" && content !== false);
|
return (typeof content !== "undefined" && content !== false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getProxyEndpoint() {
|
getProxyMeta() {
|
||||||
return $("meta[name=pv-proxy-endpoint]").attr("content");
|
return getContent("meta[name=pv-proxy-endpoint]");
|
||||||
},
|
},
|
||||||
getLocalData() {
|
getLocalMeta() {
|
||||||
return $("meta[name=pv-cache-path]").attr("content");
|
return getContent("meta[name=pv-cache-path]");
|
||||||
},
|
},
|
||||||
hasProxyEndpoint() {
|
hasProxyMeta() {
|
||||||
return hasContent("meta[name=pv-proxy-endpoint]");
|
return hasContent("meta[name=pv-proxy-endpoint]");
|
||||||
},
|
},
|
||||||
hasLocalData() {
|
hasLocalMeta() {
|
||||||
return hasContent("meta[name=pv-cache-path]");
|
return hasContent("meta[name=pv-cache-path]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}());
|
}());
|
||||||
|
|
||||||
const PvStorage = (function () {
|
const PvStorage = (function () {
|
||||||
const KEY_PV = "pv";
|
const Keys = {
|
||||||
const KEY_CREATION = "pv_created_date";
|
KEY_PV: "pv",
|
||||||
|
KEY_PV_SRC: "pv_src",
|
||||||
|
KEY_CREATION: "pv_created_date"
|
||||||
|
};
|
||||||
|
|
||||||
|
const Source = {
|
||||||
|
LOCAL: "same-origin",
|
||||||
|
PROXY: "cors"
|
||||||
|
};
|
||||||
|
|
||||||
function get(key) {
|
function get(key) {
|
||||||
return localStorage.getItem(key);
|
return localStorage.getItem(key);
|
||||||
|
@ -51,35 +63,54 @@ const PvStorage = (function () {
|
||||||
localStorage.setItem(key, val);
|
localStorage.setItem(key, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function saveCache(pv, src) {
|
||||||
|
set(Keys.KEY_PV, pv);
|
||||||
|
set(Keys.KEY_PV_SRC, src);
|
||||||
|
set(Keys.KEY_CREATION, new Date().toJSON());
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
keysCount() {
|
||||||
|
return Object.keys(Keys).length;
|
||||||
|
},
|
||||||
hasCache() {
|
hasCache() {
|
||||||
return (localStorage.getItem(KEY_PV) !== null);
|
return (localStorage.getItem(Keys.KEY_PV) !== null);
|
||||||
},
|
},
|
||||||
getCache() {
|
getCache() {
|
||||||
// get data from browser cache
|
return JSON.parse(localStorage.getItem(Keys.KEY_PV));
|
||||||
return JSON.parse(localStorage.getItem(KEY_PV));
|
|
||||||
},
|
},
|
||||||
saveCache(pv) {
|
saveLocalCache(pv) {
|
||||||
set(KEY_PV, pv);
|
saveCache(pv, Source.LOCAL);
|
||||||
set(KEY_CREATION, new Date().toJSON());
|
},
|
||||||
|
saveProxyCache(pv) {
|
||||||
|
saveCache(pv, Source.PROXY);
|
||||||
},
|
},
|
||||||
isExpired() {
|
isExpired() {
|
||||||
let date = new Date(get(KEY_CREATION));
|
let date = new Date(get(Keys.KEY_CREATION));
|
||||||
date.setHours(date.getHours() + 1); // per hour
|
date.setHours(date.getHours() + 1); // per hour
|
||||||
return Date.now() >= date.getTime();
|
return Date.now() >= date.getTime();
|
||||||
},
|
},
|
||||||
getAllPageviews() {
|
isFromLocal() {
|
||||||
return PvStorage.getCache().totalsForAllResults["ga:pageviews"];
|
return get(Keys.KEY_PV_SRC) === Source.LOCAL;
|
||||||
|
},
|
||||||
|
isFromProxy() {
|
||||||
|
return get(Keys.KEY_PV_SRC) === Source.PROXY;
|
||||||
},
|
},
|
||||||
newerThan(pv) {
|
newerThan(pv) {
|
||||||
return PvStorage.getAllPageviews() > pv.totalsForAllResults["ga:pageviews"];
|
return PvStorage.getCache().totalsForAllResults["ga:pageviews"] > pv.totalsForAllResults["ga:pageviews"];
|
||||||
},
|
},
|
||||||
inspectKeys() {
|
inspectKeys() {
|
||||||
|
if (localStorage.length !== PvStorage.keysCount()) {
|
||||||
|
localStorage.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for(let i = 0; i < localStorage.length; i++){
|
for(let i = 0; i < localStorage.length; i++){
|
||||||
const key = localStorage.key(i);
|
const key = localStorage.key(i);
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case KEY_PV:
|
case Keys.KEY_PV:
|
||||||
case KEY_CREATION:
|
case Keys.KEY_PV_SRC:
|
||||||
|
case Keys.KEY_CREATION:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
|
@ -152,14 +183,14 @@ function displayPageviews(data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchProxyPageviews() {
|
function fetchProxyPageviews() {
|
||||||
if (PvOpts.hasProxyEndpoint()) {
|
if (PvOpts.hasProxyMeta()) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
url: PvOpts.getProxyEndpoint(),
|
url: PvOpts.getProxyMeta(),
|
||||||
dataType: "jsonp",
|
dataType: "jsonp",
|
||||||
jsonpCallback: "displayPageviews",
|
jsonpCallback: "displayPageviews",
|
||||||
success: (data, textStatus, jqXHR) => {
|
success: (data) => {
|
||||||
PvStorage.saveCache(JSON.stringify(data));
|
PvStorage.saveProxyCache(JSON.stringify(data));
|
||||||
},
|
},
|
||||||
error: (jqXHR, textStatus, errorThrown) => {
|
error: (jqXHR, textStatus, errorThrown) => {
|
||||||
console.log("Failed to load pageviews from proxy server: " + errorThrown);
|
console.log("Failed to load pageviews from proxy server: " + errorThrown);
|
||||||
|
@ -168,26 +199,19 @@ function fetchProxyPageviews() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadPageviews(hasCache = false) {
|
function fetchLocalPageviews(hasCache = false) {
|
||||||
if (PvOpts.hasLocalData()) {
|
return fetch(PvOpts.getLocalMeta())
|
||||||
fetch(PvOpts.getLocalData())
|
.then(response => response.json())
|
||||||
.then((response) => response.json())
|
.then(data => {
|
||||||
.then((data) => {
|
if (hasCache) {
|
||||||
// The cache from the proxy will sometimes be more recent than the local one
|
// The cache from the proxy will sometimes be more recent than the local one
|
||||||
if (hasCache && PvStorage.newerThan(data)) {
|
if (PvStorage.isFromProxy() && PvStorage.newerThan(data)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
displayPageviews(data);
|
}
|
||||||
PvStorage.saveCache(JSON.stringify(data));
|
displayPageviews(data);
|
||||||
})
|
PvStorage.saveLocalCache(JSON.stringify(data));
|
||||||
.then(() => {
|
});
|
||||||
fetchProxyPageviews();
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
fetchProxyPageviews();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
|
@ -199,11 +223,27 @@ $(function() {
|
||||||
|
|
||||||
if (PvStorage.hasCache()) {
|
if (PvStorage.hasCache()) {
|
||||||
displayPageviews(PvStorage.getCache());
|
displayPageviews(PvStorage.getCache());
|
||||||
if (!PvStorage.isExpired()) {
|
|
||||||
return;
|
if (PvStorage.isExpired()) {
|
||||||
|
if (PvOpts.hasLocalMeta()) {
|
||||||
|
fetchLocalPageviews(true).then(fetchProxyPageviews);
|
||||||
|
} else {
|
||||||
|
fetchProxyPageviews();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (PvStorage.isFromLocal()) {
|
||||||
|
fetchProxyPageviews();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { // no cached
|
||||||
|
|
||||||
|
if (PvOpts.hasLocalMeta()) {
|
||||||
|
fetchLocalPageviews().then(fetchProxyPageviews);
|
||||||
|
} else {
|
||||||
|
fetchProxyPageviews();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadPageviews(PvStorage.hasCache());
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
2
assets/js/dist/pvreport.min.js
vendored
2
assets/js/dist/pvreport.min.js
vendored
|
@ -3,4 +3,4 @@
|
||||||
* © 2019 Cotes Chung
|
* © 2019 Cotes Chung
|
||||||
* MIT Licensed
|
* MIT Licensed
|
||||||
*/
|
*/
|
||||||
const getInitStatus=function(){let t=!1;return()=>{var e=t;return t=t||!0,e}}(),PvOpts=function(){function e(e){e=$(e).attr("content");return void 0!==e&&!1!==e}return{getProxyEndpoint(){return $("meta[name=pv-proxy-endpoint]").attr("content")},getLocalData(){return $("meta[name=pv-cache-path]").attr("content")},hasProxyEndpoint(){return e("meta[name=pv-proxy-endpoint]")},hasLocalData(){return e("meta[name=pv-cache-path]")}}}(),PvStorage=function(){const t="pv",a="pv_created_date";function r(e,t){localStorage.setItem(e,t)}return{hasCache(){return null!==localStorage.getItem(t)},getCache(){return JSON.parse(localStorage.getItem(t))},saveCache(e){r(t,e),r(a,(new Date).toJSON())},isExpired(){let e=new Date((t=a,localStorage.getItem(t)));var t;return e.setHours(e.getHours()+1),Date.now()>=e.getTime()},getAllPageviews(){return PvStorage.getCache().totalsForAllResults["ga:pageviews"]},newerThan(e){return PvStorage.getAllPageviews()>e.totalsForAllResults["ga:pageviews"]},inspectKeys(){for(let e=0;e<localStorage.length;e++)switch(localStorage.key(e)){case t:case a:break;default:return void localStorage.clear()}}}}();function countUp(t,a,r){if(t<a){let e=new CountUp(r,t,a);e.error?console.error(e.error):e.start()}}function countPV(t,a){let r=0;if(void 0!==a)for(let e=0;e<a.length;++e)if(a[parseInt(e,10)][0]===t){r+=parseInt(a[parseInt(e,10)][1],10);break}return r}function tacklePV(e,t,a,r){let n=countPV(t,e);n=0===n?1:n,r?(r=parseInt(a.text().replace(/,/g,""),10),n>r&&countUp(r,n,a.attr("id"))):a.text((new Intl.NumberFormat).format(n))}function displayPageviews(e){if(void 0!==e){let t=getInitStatus();const a=e.rows;0<$("#post-list").length?$(".post-preview").each(function(){var e=$(this).find("a").attr("href");tacklePV(a,e,$(this).find(".pageviews"),t)}):0<$(".post").length&&(e=window.location.pathname,tacklePV(a,e,$("#pv"),t))}}function fetchProxyPageviews(){PvOpts.hasProxyEndpoint()&&$.ajax({type:"GET",url:PvOpts.getProxyEndpoint(),dataType:"jsonp",jsonpCallback:"displayPageviews",success:(e,t,a)=>{PvStorage.saveCache(JSON.stringify(e))},error:(e,t,a)=>{console.log("Failed to load pageviews from proxy server: "+a)}})}function loadPageviews(t=!1){PvOpts.hasLocalData()?fetch(PvOpts.getLocalData()).then(e=>e.json()).then(e=>{t&&PvStorage.newerThan(e)||(displayPageviews(e),PvStorage.saveCache(JSON.stringify(e)))}).then(()=>{fetchProxyPageviews()}):fetchProxyPageviews()}$(function(){$(".pageviews").length<=0||(PvStorage.inspectKeys(),PvStorage.hasCache()&&(displayPageviews(PvStorage.getCache()),!PvStorage.isExpired())||loadPageviews(PvStorage.hasCache()))});
|
const getInitStatus=function(){let t=!1;return()=>{var e=t;return t=t||!0,e}}(),PvOpts=function(){function t(e){return $(e).attr("content")}function e(e){e=t(e);return void 0!==e&&!1!==e}return{getProxyMeta(){return t("meta[name=pv-proxy-endpoint]")},getLocalMeta(){return t("meta[name=pv-cache-path]")},hasProxyMeta(){return e("meta[name=pv-proxy-endpoint]")},hasLocalMeta(){return e("meta[name=pv-cache-path]")}}}(),PvStorage=function(){const a={KEY_PV:"pv",KEY_PV_SRC:"pv_src",KEY_CREATION:"pv_created_date"},t={LOCAL:"same-origin",PROXY:"cors"};function r(e){return localStorage.getItem(e)}function o(e,t){localStorage.setItem(e,t)}function n(e,t){o(a.KEY_PV,e),o(a.KEY_PV_SRC,t),o(a.KEY_CREATION,(new Date).toJSON())}return{keysCount(){return Object.keys(a).length},hasCache(){return null!==localStorage.getItem(a.KEY_PV)},getCache(){return JSON.parse(localStorage.getItem(a.KEY_PV))},saveLocalCache(e){n(e,t.LOCAL)},saveProxyCache(e){n(e,t.PROXY)},isExpired(){let e=new Date(r(a.KEY_CREATION));return e.setHours(e.getHours()+1),Date.now()>=e.getTime()},isFromLocal(){return r(a.KEY_PV_SRC)===t.LOCAL},isFromProxy(){return r(a.KEY_PV_SRC)===t.PROXY},newerThan(e){return PvStorage.getCache().totalsForAllResults["ga:pageviews"]>e.totalsForAllResults["ga:pageviews"]},inspectKeys(){if(localStorage.length===PvStorage.keysCount())for(let e=0;e<localStorage.length;e++)switch(localStorage.key(e)){case a.KEY_PV:case a.KEY_PV_SRC:case a.KEY_CREATION:break;default:return void localStorage.clear()}else localStorage.clear()}}}();function countUp(t,a,r){if(t<a){let e=new CountUp(r,t,a);e.error?console.error(e.error):e.start()}}function countPV(t,a){let r=0;if(void 0!==a)for(let e=0;e<a.length;++e)if(a[parseInt(e,10)][0]===t){r+=parseInt(a[parseInt(e,10)][1],10);break}return r}function tacklePV(e,t,a,r){let o=countPV(t,e);o=0===o?1:o,r?(r=parseInt(a.text().replace(/,/g,""),10),o>r&&countUp(r,o,a.attr("id"))):a.text((new Intl.NumberFormat).format(o))}function displayPageviews(e){if(void 0!==e){let t=getInitStatus();const a=e.rows;0<$("#post-list").length?$(".post-preview").each(function(){var e=$(this).find("a").attr("href");tacklePV(a,e,$(this).find(".pageviews"),t)}):0<$(".post").length&&(e=window.location.pathname,tacklePV(a,e,$("#pv"),t))}}function fetchProxyPageviews(){PvOpts.hasProxyMeta()&&$.ajax({type:"GET",url:PvOpts.getProxyMeta(),dataType:"jsonp",jsonpCallback:"displayPageviews",success:e=>{PvStorage.saveProxyCache(JSON.stringify(e))},error:(e,t,a)=>{console.log("Failed to load pageviews from proxy server: "+a)}})}function fetchLocalPageviews(t=!1){return fetch(PvOpts.getLocalMeta()).then(e=>e.json()).then(e=>{t&&PvStorage.isFromProxy()&&PvStorage.newerThan(e)||(displayPageviews(e),PvStorage.saveLocalCache(JSON.stringify(e)))})}$(function(){$(".pageviews").length<=0||(PvStorage.inspectKeys(),PvStorage.hasCache()?(displayPageviews(PvStorage.getCache()),PvStorage.isExpired()?PvOpts.hasLocalMeta()?fetchLocalPageviews(!0).then(fetchProxyPageviews):fetchProxyPageviews():PvStorage.isFromLocal()&&fetchProxyPageviews()):PvOpts.hasLocalMeta()?fetchLocalPageviews().then(fetchProxyPageviews):fetchProxyPageviews())});
|
Loading…
Reference in a new issue