Team:HSAAHNU Anhui/inject.js

From 2014hs.igem.org

(Difference between revisions)
(for mobile)
(fix a bug when loading a new page PJAX listener wouldn't listen)
Line 92: Line 92:
   if (isJQueryUpdated && isNProgressLoaded) {
   if (isJQueryUpdated && isNProgressLoaded) {
     alert('done');
     alert('done');
-
     resumeInitAfterComponentsLoaded();
+
     completePageSpecificJobs();
   }
   }
   else {
   else {
Line 142: Line 142:
   var next = href.substr(basePath.length).split('#');
   var next = href.substr(basePath.length).split('#');
-
   var isSamePage = current[0] == next[0];
+
   var isSamePage = current[0] === next[0];
   if (isSamePage)
   if (isSamePage)
     return false;
     return false;
Line 155: Line 155:
var PJAXEnabledOnce = false;
var PJAXEnabledOnce = false;
function setupPJAXListener () {
function setupPJAXListener () {
-
   if (history == null) {
+
   if (history === null) {
     alert('sorry but your browser does not support history api.');
     alert('sorry but your browser does not support history api.');
     return;
     return;
Line 187: Line 187:
function completePageSpecificJobs () {
function completePageSpecificJobs () {
 +
  setupPJAXListener();
 +
   var metadata = $('#metadata')[0].innerText;
   var metadata = $('#metadata')[0].innerText;
   metadata = JSON.parse(metadata);
   metadata = JSON.parse(metadata);
   metadata.title ? $('title')[0].innerText = metadata.title : null;
   metadata.title ? $('title')[0].innerText = metadata.title : null;
-
}
 
-
 
-
function resumeInitAfterComponentsLoaded () {
 
-
  setupPJAXListener();
 
-
  completePageSpecificJobs();
 
}
}

Revision as of 02:08, 10 June 2014

/*

* Basically this script will do the following thing:
* Remove old styles.
* Remove old script tags.
* Apply common stylesheets. (Bootstrap, NProgress)
* Apply common scripts. (jQuery, Bootstrap, NProgress)
* Update jQuery.
* move inner HTML of main tag to body tag for clarity.
* Clean up script tags in head tag for debugging purpose.
* Set up PJAX for better performance.
* Complete page specific jobs.
*/

var commonStylesheets = [

 'http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css',
 'http://ricostacruz.com/nprogress/nprogress.css',
 '/Team:HSAAHNU_Anhui/normalize.css?action=raw&ctype=text/css'

];

var commonScripts = [

 'http://code.jquery.com/jquery-1.11.1.min.js',
 'http://ricostacruz.com/nprogress/nprogress.js'

];

function cleanup () {

 function removeNodesFromHead (tag, constriant) {
   constriant = constriant ? constriant
                           : function () { return true; };
   var nodes = document.head.getElementsByTagName(tag);
   var failedCounter = 0;
   var iterator = 0;
   while (nodes.length !== failedCounter) {
     var node = nodes[iterator];
     if (constriant(node))
       document.head.removeChild(node);
     else {
       failedCounter ++;
       iterator ++;
     }
   }
 };
 removeNodesFromHead('style');
 removeNodesFromHead('script');
 removeNodesFromHead('link', function (node) {
   var isStylesheet = node.rel === 'stylesheet';
   return isStylesheet;
 });
 var main = document.body.getElementsByTagName('main')[0];
 document.body.innerHTML = main.innerHTML;

}

function applyCommonResources () {

 function applyResources (factory, urls) {
   urls.forEach(function (url) {
     var node = factory(url);
     document.head.appendChild(node);
   });
 };
 applyResources(function (url) {
   var node = document.createElement('link');
   node.href = url;
   node.rel = 'stylesheet';
   return node;
 }, commonStylesheets);
 applyResources(function (url) {
   var node = document.createElement('script');
   node.src = url;
   return node;
 }, commonScripts);
 var meta = document.createElement('meta');
 meta.name = 'viewport';
 meta.content = 'width=device-width, initial-scale=1';
 document.head.appendChild(meta);

}

var crucialComponentLoadingTime = 0; function waitForComponents () {

 //16 seconds is long enough.
 var isLoadFailed = crucialComponentLoadingTime >= 32;
 if (isLoadFailed) {
   alert('One component of this page failed to load. Please refresh!');
   return;
 }
 var isJQueryUpdated = window.hasOwnProperty('jQuery') &&
                       $.fn.jquery === '1.11.1';
 var isNProgressLoaded = window.hasOwnProperty('NProgress');
 if (isJQueryUpdated && isNProgressLoaded) {
   alert('done');
   completePageSpecificJobs();
 }
 else {
   crucialComponentLoadingTime ++;
   setTimeout(waitForComponents, 500);
 }

}

document.addEventListener('DOMContentLoaded', function () {

 cleanup();
 applyCommonResources();
 waitForComponents();

});

function fetchData (path, callback) {

 var isPathString = typeof path === 'string';
 if (!isPathString) {
   var team = '/Team:HSAAHNU_Anhui';
   var query = '?action=raw&ctype=text/css';
   path = team + path.href + query;
 }
 $.ajax(path).done(function (data) {
   callback(null, data);
 });

}

function loadNewPage (path) {

 NProgress.start();
 fetchData(path, function (err, data) {
   data = data.split('<main>')[1];
   data = data.split('</main>')[0];
   document.body.innerHTML = data;
   completePageSpecificJobs();
   NProgress.done();
 });

}

function startsWith (lhs, rhs) {

 return lhs.substr(0, rhs.length) === rhs;

}

function analyzeAnchor (href) {

 var basePath = 'https://2014hs.igem.org/Team:HSAAHNU_Anhui';
 var isOutsideLink = !startsWith(href, basePath);
 if (isOutsideLink)
   return false;
 var current = document.URL.substr(basePath.length).split('#');
 var next = href.substr(basePath.length).split('#');
 var isSamePage = current[0] === next[0];
 if (isSamePage)
   return false;
 return {
   href: next[0],
   anchor: next[1],
 };

}


var PJAXEnabledOnce = false; function setupPJAXListener () {

 if (history === null) {
   alert('sorry but your browser does not support history api.');
   return;
 }
 alert('it works.');
 function anchorClickListener (event) {
   var node = event.target;
   var path = analyzeAnchor(node.href);
   if (path === false)
     return true;
   history.pushState(null, null, node.href);
   loadNewPage(path);
   if (!PJAXEnabledOnce) {
     PJAXEnabledOnce = true;
     window.addEventListener('popstate', goBackListener);
   }
   return false;
 }
 function goBackListener (event) {
   console.log('Go back to last path:', document.URL);
   loadNewPage(document.URL);
 }
 $('a').click(anchorClickListener);

}

function completePageSpecificJobs () {

 setupPJAXListener();
 var metadata = $('#metadata')[0].innerText;
 metadata = JSON.parse(metadata);
 metadata.title ? $('title')[0].innerText = metadata.title : null;

}