Skip to content
Draft
18 changes: 1 addition & 17 deletions _layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -255,28 +255,12 @@ <h2>Related articles</h2>
</script>
{% endif %}
<script src="{{ '/assets/js/timeme.min.js' | relative_url }}"></script>
<script type="text/javascript">
// Initialize library and start tracking time
TimeMe.initialize({
currentPageName: window.location.pathname,
idleTimeoutInSeconds: 5 // seconds
});
</script>
<script type="module" src="{{ '/assets/js/ubi.js' | relative_url }}"></script>
<script type="text/javascript">
// Initialize library and start tracking time
TimeMe.initialize({
currentPageName: window.location.pathname,
idleTimeoutInSeconds: 5 // seconds
});
TimeMe.startTimer(window.location.pathname);
</script>

{% if site.search_enabled == false and site.use_custom_search == true %}
<script type="module" defer src="{{ '/assets/js/search.js' | relative_url }}"></script>
{% endif %}
<script src="{{ '/assets/js/copy-button.js' | relative_url }}"></script>
<script src="{{ '/assets/js/nav-scroll.js' | relative_url }}"></script>
<script src="{{ '/assets/js/listener.js' | relative_url }}"></script>
<script type="module" src="{{ '/assets/js/listener.js' | relative_url }}"></script>
</body>
</html>
20 changes: 19 additions & 1 deletion assets/js/listener.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as UBI from "./ubi.js";

const yesButton = document.getElementById('yes');
const noButton = document.getElementById('no');
const numCharsLabel = document.getElementById('num-chars');
Expand Down Expand Up @@ -48,7 +50,7 @@ function updateTextArea() {
}

// calculate the number of characters remaining
counter = 350 - commentTextArea.value.length;
const counter = 350 - commentTextArea.value.length;
numCharsLabel.innerText = counter + " characters left";
}

Expand All @@ -68,6 +70,22 @@ function sendFeedback() {

if (helpful === 'none' && comment === 'none') return;

try{
let e = new UBI.UbiEvent('user_feedback', {
message: `Relevance: ${helpful}, Comment: ${comment}`,
event_attributes:{
url:location.pathname,
helpful:helpful,
comment:comment
}
});
e.message_type = 'USER';
UBI.logEvent(e);

} catch(e){
console.warn(`UBI Error: ${e}`)
}

// split the comment into 100-char parts because of GA limitation on custom dimensions
const commentLines = ["", "", "", ""];
for (let i = 0; i <= (comment.length - 1)/100; i++) {
Expand Down
144 changes: 92 additions & 52 deletions assets/js/ubi.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

function guiid() {
let id = '123456-insecure';
try {
Expand Down Expand Up @@ -28,11 +29,10 @@ export function hash(str, seed=42) {


/**
* In place of true authentication, this makes a hash out of the user's IP address and browser
* for tracking individual user behavior
* user_id = hash( user ip ) + '::' + hash( userAgent )
* In place of true authentication, this makes a hash out of the user's cookie,
* which at the moment is _ga...
*
* NOTE: if this function is called, but user_id starts with 'USER-',
* NOTE: if this function is called, but user_id starts with 'U-',
* the function below did not complete successfully,
* and userError() was called instead
* @returns
Expand All @@ -41,68 +41,47 @@ export async function initialize(){
let i = 1;

try {


if(!sessionStorage.hasOwnProperty('session_id')) {
sessionStorage.setItem('session_id', guiid());
sessionStorage.setItem('session_id', 'S-' + guiid());
}

if(sessionStorage.hasOwnProperty('user_id')){
console.log('Already initialized UBI');
return;
}

var rq = new XMLHttpRequest;

rq.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
if(this.response != null) {

//make a new user id: user ip + '::' + hash( userAgent )
let client_id = '';
if( window.navigator != null && window.navigator.userAgent != null){
client_id = window.navigator.userAgent;
} else {
client_id = guiid();
}
let user_id = hash( this.response.ip ) + '::' + hash( client_id );
sessionStorage.setItem('user_id', user_id);
console.log('user_id: ' + user_id);

}
}
};

rq.onerror = function(){
// currently, the only cookie is gtag's client_id et al.
if(document.cookie && document.cookie.length > 0){
setUserId(hash(document.cookie));
return;
} else {
//back up user_id method
userError();
if(this.error != null && this.error != ''){
console.error('ERROR Retrieving user info: ' + this.error);
}
else
console.error('UNSPECIFIED ERROR Retrieving user info');
}

rq.open("GET", "https://api64.ipify.org?format=json", true);
rq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
rq.responseType = "json";
rq.send();

} catch(error){
console.log(error)
}
}

/**
* back up method to make a user individual
* Back up method to make a user individual
* Note that this is basically the same as a session id since it would
* generate each time a user lands on the site
* @returns
*/
function userError(){
let user_id = 'USER-' + guiid();
sessionStorage.setItem('user_id', user_id);
let user_id = guiid();
setUserId(user_id);
return user_id;
}


export function genQueryId(){
const qid = 'QUERY-' + guiid();
const qid = 'Q-' + guiid();
sessionStorage.setItem('query_id', qid);
return qid;
}
Expand All @@ -113,7 +92,7 @@ export function getQueryId(){
/**
* Save explicitly, if conditions are right
*/
export function saveQueryId(query_id){
export function setQueryId(query_id){
sessionStorage.setItem('query_id', query_id);
}

Expand All @@ -124,7 +103,7 @@ export function clearCache() {

export function cacheQueryResults(results){
let qid = genQueryId();
saveQueryId(qid);
setQueryId(qid);

if(results.length > 0){
let search_results = {};
Expand All @@ -142,6 +121,10 @@ export function cacheQueryResults(results){
return [qid, []];
}

export function setUserId(user_id){
sessionStorage.setItem('user_id', 'U-' + user_id);
}

export function getUserId(){
if(sessionStorage.hasOwnProperty('user_id')){
return sessionStorage.getItem('user_id');
Expand All @@ -164,23 +147,48 @@ export function getPageId(){
return location.pathname;
}

function getTrail(){
let trail = sessionStorage.getItem('trail');
if(trail == null)
return '';
return trail;
}

function setTrail(){
let trail = getTrail();
if(trail && trail.length > 0){
if(!trail.startsWith(window.location.pathname)){
trail += ` › ${window.location.pathname}`;
}
} else {
trail = window.location.pathname;
}
sessionStorage.setItem('trail', trail);

return trail;
}

window.addEventListener("DOMContentLoaded", function (e) {
try{
initialize();
TimeMe.currentPageName = this.window.location.href;
TimeMe.initialize({
currentPageName: window.location.href,
idleTimeoutInSeconds: 5
});
setTrail();
TimeMe.startTimer(window.location.pathname);
} catch(e){

} catch(error){
console.warn(error);
}
});

window.addEventListener("beforeunload", function (e) {
try{
TimeMe.stopTimer(window.location.pathname);
logDwellTime('page_exit', window.location.pathname,
TimeMe.getTimeOnPageInSeconds(window.location.pathname));
} catch(e){

TimeMe.getTimeOnPageInSeconds(window.location.pathname));
} catch(error){
console.warn(error);
}
});

Expand Down Expand Up @@ -235,7 +243,11 @@ export class UbiPosition{
this.ordinal = ordinal;
this.x = x;
this.y = y;
this.trail = trail;
if(trail)
this.trail = trail;
else {
console.log(document.referrer);
}
}
}

Expand All @@ -252,10 +264,37 @@ export class UbiEventAttributes {
if(attributes != null){
Object.assign(this, attributes);
}
if(object != null && object != {}){
if(object != null && Object.keys(object).length > 0){
this.object = object;
}
this.position = position;
if(position != null && Object.keys(position).length > 0){
this.position = position;
}
this.setDefaultValues();
}

setDefaultValues(){
try{
if(!this.hasOwnProperty('dwell_seconds') && typeof TimeMe !== 'undefined'){
this.dwell_seconds = TimeMe.getTimeOnPageInSeconds(window.location.pathname);
}

if(!this.hasOwnProperty('browser')){
this.browser = window.navigator.userAgent;
}

if(!this.hasOwnProperty('position') || this.position == null){
const trail = getTrail();
if(trail.length > 0){
this.position = new UbiPosition({trail:trail});
}
}

// TODO: set IP
}
catch(error){

}
}
}

Expand Down Expand Up @@ -284,7 +323,8 @@ export class UbiEvent {
* @returns
*/
static replacer(key, value){
if(value == null) {
if(value == null ||
(value.constructor == Object && Object.keys(value).length === 0)) {
return undefined;
}
return value;
Expand Down