window.*

Current window

window_checks
w_current
w_parent

this window

new window




    var myWindow,
      wtr = document.getElementById("window_test_result");
    function openWin() {
        "http://web-engineer-book/js-browser.html#window",
        "myWindow",
        "width=250, height=250"
      );
    }
    function checkWin() {
      if (!myWindow) {
        wtr.innerHTML = "myWindow has never been opened!";
      } else {
        if (myWindow.closed) {
          wtr.innerHTML = "myWindow has been closed!";
        } else {
          wtr.innerHTML = "myWindow has not been closed!";
        }
      }
    }
    function closeWin(){ if(myWindow){ myWindow.close(); } }
    function resizeWinTo() {
      myWindow.resizeTo(800, 600); myWindow.focus();
    }
    function resizeWinBy() {
      myWindow.resizeBy(-100, -50); myWindow.focus();
    }
    function moveWinTo() {
      myWindow.moveTo(150, 150); myWindow.focus();
    }

    function moveWinBy() {
      myWindow.moveBy(75, 50); myWindow.focus();
    }

    function scrollWin(x, y) {
      window.scrollBy(x, y);
    }
    function scrollWinTo(x, y) {
      window.scrollTo(x, y);
    }

    var wc = document.getElementById("window_current");
    var wp = document.getElementById("window_parent");
    var w_current = window.self;
    var w_parent = window.parent;
    var w_checks = document.getElementById("window_checks");
    function windows_tests() {
      wc.innerHTML = "w_current.name = " + w_current.name +
      "w_current.status = " + w_current.status +
      // .....
      "w_current.location = " + w_current.location;

      wp.innerHTML = "w_parent.name = " + w_parent.name +
      "w_parent.status = " + w_parent.status +
      // .....
      "w_parent.location = " + w_parent.location;

      w_checks.innerHTML = "";
      if (window.matchMedia("(max-width: 700px)").matches) {
        w_checks.innerHTML += "viewport width <= 700 pixels";
      } else {
        w_checks.innerHTML += "viewport width > 700 pixels";
      }

      w_checks.innerHTML += "this box width: " +
      window.getComputedStyle(w_checks, null).getPropertyValue("width");

      var str = "Hello World!";
      var enc = window.btoa(str);
      var dec = window.atob(enc);
      w_checks.innerHTML += "Encoded String: " + enc + "Decoded String: " + dec;

      w_checks.innerHTML += "text selection (window.getSelection()):" + window.getSelection();
      w_checks.innerHTML += "selections count: " + window.getSelection().rangeCount;
    }
    setInterval(windows_tests,200);

    // matchMedia listeners
    function matchMediaFunction(x) {
      if (x.matches) { // If media query matches
        document.body.style.backgroundColor = "yellow";
      } else {
        document.body.style.backgroundColor = "pink";
      }
    }
    var x = window.matchMedia("(min-width: 700px)")
    matchMediaFunction(x) // Call listener function at run time
    x.addListener(matchMediaFunction) // Attach listener function on state changes

    all computed styles of an object
    cssObj = window.getComputedStyle(elem, null)
    for (i = 0; i < cssObj.length; i++) {
        cssObjProp = cssObj.item(i)
        txt += cssObjProp + " = " + cssObj.getPropertyValue(cssObjProp);
    }

    // computed styles of a first letter (usage of pseudo element)
    // window.getComputedStyle(elem, "first-letter").getPropertyValue("font-size");
  

screen.*


    var st = document.getElementById("screen_test");

    screen.or = (screen.msOrientation||screen.orientation||screen.mozOrientation);
    screen.lock_or = (screen.lockOrientation||screen.mozLockOrientation||screen.msLockOrientation);
    screen.unlock_or = (
      screen.unlockOrientation ||
      screen.mozUnlockOrientation ||
      screen.msUnlockOrientation ||
      ( screen.orientation && screen.orientation.unlock )
    );
    // or.onchange = function(e) { screen_tests() }
    screen.or.addEventListener('change', function(e) { screen_tests() });
    function lock_or() {
      screen.lock_or( document.getElementById("or_select").value );
    }
    function unlock_or() {
      screen.unlock_or();
    }

    function getDocumentPPI() {
      var elem = document.createElement('div');
      elem.style.width = '1in';
      document.body.appendChild(elem);
      var ppi = elem.offsetWidth;
      // var ppi = document.defaultView.getComputedStyle(elem, null).getPropertyValue('width');
      document.body.removeChild(elem);
      return ppi;
    }

    function screen_tests() {
      st.innerHTML = "screen.availWidth: " + screen.availWidth +
      "screen.availHeight: " + screen.availHeight +
      "screen.width: " + screen.width +
      "screen.height: " + screen.height +
      "screen.colorDepth: " + screen.colorDepth +
      "screen.orientation.type : " + screen.or.type +
      "screen.orientation.angle : " + screen.or.angle +
      "getDocumentPPI(): " + getDocumentPPI();
    }
    setInterval(screen_tests,1000);
  

location.*


    var location_test = document.getElementById("location_test");
    location_test.innerHTML = "location.protocol: " + location.protocol +
    "location.hostname: " + location.hostname +
    "location.port: " + location.port +
    "location.origin: " + location.origin +
    "location.href: " + location.href +
    "location.host: " + location.host +
    "location.pathname: " + location.pathname +
    "location.hash: " + location.hash +
    "location.search: " + location.search;
  

history.*

AJAX navigation

include/*


    <!-- include/header.php -->
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <script type="text/javascript" src="../js/ajax_nav.js"></script>
    <link rel="stylesheet" href="../css/style.css" />

    <!-- include/before_content.php -->
    <p>
      <a class="ajax-nav" href="first_page.php">First example</a>
      <a class="ajax-nav" href="second_page.php">Second example</a>
      <a class="ajax-nav" href="third_page.php">Third example</a>
      <a class="ajax-nav" href="unexisting.php">Unexisting page</a>
    </p>

    <!-- include/after_content.php -->
    <p>This is the footer. It is shared between all ajax pages.</p>
  

first_page.php , ...


    <?php
    $page_title = "First page";
    $as_json = false;
    if (isset($_GET["view_as"]) && $_GET["view_as"] == "json") {
      $as_json = true;
      ob_start();
    } else {
      ?>
      <!doctype html>
      <html>
      <head>
        <?php
        include "include/header.php";
        echo "<title>" . $page_title . "</title>";
        ?>
      </head>

      <body>

      <?php include "include/before_content.php"; ?>

      <p>This paragraph is ...</p>

      <div id="ajax-content">
    <?php } ?>

      <p>This is the content of <strong>first_page.php</strong>.</p>

    <?php
    if ($as_json) {
      echo json_encode(array("page" => $page_title, "content" => ob_get_clean()));
    } else {
      ?>
      </div>

      <p>This paragraph is ...</p>

      <?php
      include "include/after_content.php";
      echo "</body>\n</html>";
    }
  

js/ajax_nav.js


    "use strict";
    const ajaxRequest = new (function () {
      const sTargetId = "ajax-content",
        sViewKey = "view_as",
        sAjaxClass = "ajax-nav",
        rSearch = /\?.*$/,
        rHost = /^[^\?]*\?*&*/,
        rView = new RegExp("&" + sViewKey + "\\=[^&]*|&*$", "i"),
        rEndQstMark = /\?$/,
        oLoadingBox = document.createElement("div"),
        oCover = document.createElement("div"),
        oLoadingImg = new Image(),
        oPageInfo = {
          title: null,
          url: location.href
        }, oHTTPStatus = {
          100: "Continue",
          101: "Switching Protocols",
          102: "Processing",
          200: "OK",
          201: "Created",
          202: "Accepted",
          203: "Non-Authoritative Information",
          204: "No Content",
          205: "Reset Content",
          206: "Partial Content",
          207: "Multi-Status",
          208: "Already Reported",
          226: "IM Used",
          300: "Multiple Choices",
          301: "Moved Permanently",
          302: "Found",
          303: "See Other",
          304: "Not Modified",
          305: "Use Proxy",
          306: "Reserved",
          307: "Temporary Redirect",
          308: "Permanent Redirect",
          400: "Bad Request",
          401: "Unauthorized",
          402: "Payment Required",
          403: "Forbidden",
          404: "Not Found",
          405: "Method Not Allowed",
          406: "Not Acceptable",
          407: "Proxy Authentication Required",
          408: "Request Timeout",
          409: "Conflict",
          410: "Gone",
          411: "Length Required",
          412: "Precondition Failed",
          413: "Request Entity Too Large",
          414: "Request-URI Too Long",
          415: "Unsupported Media Type",
          416: "Requested Range Not Satisfiable",
          417: "Expectation Failed",
          422: "Unprocessable Entity",
          423: "Locked",
          424: "Failed Dependency",
          425: "Unassigned",
          426: "Upgrade Required",
          427: "Unassigned",
          428: "Precondition Required",
          429: "Too Many Requests",
          430: "Unassigned",
          431: "Request Header Fields Too Large",
          500: "Internal Server Error",
          501: "Not Implemented",
          502: "Bad Gateway",
          503: "Service Unavailable",
          504: "Gateway Timeout",
          505: "HTTP Version Not Supported",
          506: "Variant Also Negotiates (Experimental)",
          507: "Insufficient Storage",
          508: "Loop Detected",
          509: "Unassigned",
          510: "Not Extended",
          511: "Network Authentication Required"
        };
      function closeReq () {
        oLoadingBox.parentNode && document.body.removeChild(oLoadingBox);
        bIsLoading = false;
      }
      function abortReq () {
        if (!bIsLoading) { return; }
        oReq.abort();
        closeReq();
      }
      function ajaxError () {
        alert("Unknown error.");
      }
      function ajaxLoad () {
        var vMsg, nStatus = this.status;
        switch (nStatus) {
          case 200:
            vMsg = JSON.parse(this.responseText);
            document.title = oPageInfo.title = vMsg.page;
            document.getElementById(sTargetId).innerHTML = vMsg.content;
            if (bUpdateURL) {
              history.pushState(oPageInfo, oPageInfo.title, oPageInfo.url);
              bUpdateURL = false;
            }
            break;
          default:
            vMsg = nStatus + ": " + (oHTTPStatus[nStatus] || "Unknown");
            switch (Math.floor(nStatus / 100)) {
              /*
              case 1:
              // Informational 1xx
              console.log("Information code " + vMsg);
              break;
              case 2:
              // Successful 2xx
              console.log("Successful code " + vMsg);
              break;
              case 3:
              // Redirection 3xx
              console.log("Redirection code " + vMsg);
              break;
              */
              case 4:
                /* Client Error 4xx */
                alert("Client Error #" + vMsg);
                break;
              case 5:
                /* Server Error 5xx */
                alert("Server Error #" + vMsg);
                break;
              default:
                /* Unknown status */
                ajaxError();
            }
        }
        closeReq();
      }
      function filterURL (sURL, sViewMode) {
        return sURL.replace(rSearch, "") +
          ("?" + sURL.replace(rHost, "&").
          replace(rView, sViewMode ? "&" + sViewKey + "=" + sViewMode : "").
          slice(1)).replace(rEndQstMark, "");
      }
      function getPage (sPage) {
        if (bIsLoading) { return; }
        oReq = new XMLHttpRequest();
        bIsLoading = true;
        oReq.onload = ajaxLoad;
        oReq.onerror = ajaxError;
        if (sPage) { oPageInfo.url = filterURL(sPage, null); }
        oReq.open("get", filterURL(oPageInfo.url, "json"), true);
        oReq.send();
        oLoadingBox.parentNode || document.body.appendChild(oLoadingBox);
      }
      function requestPage (sURL) {
        if (history.pushState) {
          bUpdateURL = true;
          getPage(sURL);
        } else { // Ajax navigation is not supported
          location.assign(sURL);
        }
      }
      function processLink () {
        if (this.className === sAjaxClass) {
          requestPage(this.href);
          return false;
        }
        return true;
      }
      function init () {
        oPageInfo.title = document.title;
        for (
          var oLink, nIdx = 0, nLen = document.links.length;
          nIdx < nLen;
          document.links[nIdx++].onclick = processLink
        );
      }
      var oReq, bIsLoading = false, bUpdateURL = false;
      oLoadingBox.id = "ajax-loader";
      oCover.onclick = abortReq;
      oLoadingImg.src = "data:image/gif;base64,...==";
      oCover.appendChild(oLoadingImg);
      oLoadingBox.appendChild(oCover);
      onpopstate = function (oEvent) {
        bUpdateURL = false;
        oPageInfo.title = oEvent.state.title;
        oPageInfo.url = oEvent.state.url;
        getPage();
      };
      window.addEventListener ? addEventListener("load", init, false) :
        window.attachEvent ? attachEvent("onload", init) : (onload = init);
      // Public methods
      this.open = requestPage;
      this.stop = abortReq;
      this.rebuildLinks = init;
    })();
  

    var nt = document.getElementById("navigator_tests");
    nt.innerHTML =
      "navigator.userAgent: " + navigator.userAgent +
      "navigator.appName: " + navigator.appName +
      "navigator.appCodeName: " + navigator.appCodeName +
      "navigator.appVersion: " + navigator.appVersion +
      "navigator.product: " + navigator.product +
      "navigator.language: " + navigator.language +
      "navigator.languages: " + navigator.languages +
      "navigator.platform: " + navigator.platform +
      "navigator.cookieEnabled: " + navigator.cookieEnabled +
      "navigator.javaEnabled(): " + navigator.javaEnabled() +
      "navigator.geolocation: " + navigator.geolocation +
      "navigator.onLine: " + navigator.onLine +
      "navigator.deviceMemory: " + navigator.deviceMemory +
      "navigator.hardwareConcurrency: " + navigator.hardwareConcurrency +
      "navigator.serviceWorker: " + navigator.serviceWorker +
      "navigator.activeVRDisplays: " + navigator.activeVRDisplays +
      "navigator.maxTouchPoints: " + navigator.maxTouchPoints +
      "navigator.plugins: " + navigator.plugins +
      "navigator.oscpu: " + navigator.oscpu +
      "navigator.mimeTypes: " + navigator.mimeTypes +
      "navigator.mediaCapabilities: " + navigator.mediaCapabilities +
      "navigator.doNotTrack: " + navigator.doNotTrack +
      "window.doNotTrack: " + window.doNotTrack;

    var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection || null;
    if (connection) {
      nt.innerHTML += "navigator.connection: " + connection +
      // Network type that browser uses
      "connection.type: " + connection.type +
      // Effective bandwidth estimate
      "connection.downlink: " + connection.downlink +
      // Effective round-trip time estimate
      "connection.rtt: " + connection.rtt +
      // Upper bound on the downlink speed of the first network hop
      "connection.downlinkMax: " + connection.downlinkMax +
      // Effective connection type determined using a combination of recently
      // observed rtt and downlink values
      "connection.effectiveType: " + connection.effectiveType +
      // True if the user has requested a reduced data usage mode from the user agent
      "connection.saveData: " + connection.saveData;

      var type = connection.type;
      function updateConnectionStatus() {
        nt.innerHTML += "Connection type changed from " + type + " to " + connection.type;
      }
      connection.addEventListener('change', updateConnectionStatus);
    } else {
      nt.innerHTML += "navigator.connection NOT supported...";
    }

    if ('activeVRDisplays' in navigator) {
      nt.innerHTML += "activeVRDisplays:"
      for(var i = 0; i < navigator.activeVRDisplays.length; i++) {
        nt.innerHTML += "Display " + navigator.activeVRDisplays[i].displayId + " is active";
      }
    } else {
      nt.innerHTML += "navigator.activeVRDisplays NOT supported...";
    }

    nt.innerHTML += "Plugins:";
    for(var i = 0; i < navigator.plugins.length; i++) {
      nt.innerHTML += navigator.plugins[i].name + " - " +
      navigator.plugins[i].filename + " - " +
      navigator.plugins[i].description + " - " +
      (navigator.plugins[i].version?navigator.plugins[i].version:"");
    }

    nt.innerHTML += "mimeTypes:"
    for(var i = 0; i < navigator.mimeTypes.length; i++) {
      nt.innerHTML += "mimeType " + navigator.mimeTypes[i].type;
    }

    // obtain the usage estimates and present the percentage of storage capacity currently used to the user
    nt.innerHTML += "Percentage of storage capacity:";
    navigator.storage.estimate().then(function(estimate) {
      nt.innerHTML += (estimate.usage / estimate.quota).toFixed(2);
    });
  

geolocation


    function geoFind() {
      var gt = document.getElementById("geolocation_tests");
      if (!navigator.geolocation){
        gt.innerHTML = "Geolocation is not supported by your browser";
        return;
      }
      function geo_success(position) {
        var pos_date = new Date(position.timestamp);
        gt.innerHTML =
        "Latitude: " + position.coords.latitude + "°" +
        "Longitude: " + position.coords.longitude + "°" +
        "accuracy: " + position.coords.accuracy +
        "altitude: " + position.coords.altitude +
        "altitudeAccuracy: " + position.coords.altitudeAccuracy +
        "heading: " + position.coords.heading +
        "speed: " + position.coords.speed +
        "timestamp: " + pos_date.toDateString();
        // --- FOR <div id="mapholder"></div> :
        // var latlon = new google.maps.LatLng(lat, lon)
        // var mapholder = document.getElementById('mapholder')
        // mapholder.style.height = '250px';
        // mapholder.style.width = '500px';
        // var myOptions = {
        //   center:latlon,zoom:14,
        //   mapTypeId:google.maps.MapTypeId.ROADMAP,
        //   mapTypeControl:false,
        //   navigationControlOptions:{
        //     style:google.maps.NavigationControlStyle.SMALL
        //   }
        // }
        // var map = new google.maps.Map(document.getElementById("mapholder"), myOptions);
        // var marker = new google.maps.Marker({position:latlon,map:map,title:"You are here!"});
        // --- JUST IMAGE :
        var img = new Image();
        img.src = "https://maps.googleapis.com/maps/api/staticmap?center=" +
          latitude + "," + longitude + "&zoom=13&size=300x300&sensor=false";
        gt.appendChild(img);
      }
      function geo_error(error) {
        switch(error.code) {
          case error.PERMISSION_DENIED:
            gt.innerHTML = "User denied the request for Geolocation."
          break;
          case error.POSITION_UNAVAILABLE:
            gt.innerHTML = "Location information is unavailable."
          break;
          case error.TIMEOUT:
            gt.innerHTML = "The request to get user location timed out."
          break;
          case error.UNKNOWN_ERROR:
            gt.innerHTML = "An unknown error occurred."
          break;
        }
      }
      gt.innerHTML = "Locating";
      navigator.geolocation.getCurrentPosition(
        geo_success,
        geo_error
      );
      // navigator.geolocation.watchPosition(
      //   geo_success,
      //   geo_error,
      //   {
      //     enableHighAccuracy: false,
      //     maximumAge: 3000,
      //     timeout: 3000
      //   }
      // );
    }
  

Alert/Confirm/Prompt

confirm result...
prompt result...

    function to_confirm() {
      if (confirm("Press a button!")) {
        document.getElementById("toc").innerHTML = "You pressed OK!";
      } else {
        document.getElementById("toc").innerHTML = "You pressed Cancel!";
      }
    }
    function to_prompt() {
      var person = prompt("Please enter your name:", "Andrei");
      if (person == null || person == "") {
        document.getElementById("top").innerHTML = "User cancelled the prompt.";
      } else {
        document.getElementById("top").innerHTML = "Hello " + person + "! How are you today?";
      }
    }
  

Timing


    var timeout_clock = document.getElementById('timeout_clock'),
        interval_clock = document.getElementById('interval_clock'),
        tc,
        ic;

    var checkTime = (i) => (i<10)?"0"+i:i; // add leading zero
    function startTimeoutClock() {
      var today = new Date(),
          h = today.getHours(),
          m = today.getMinutes(),
          s = today.getSeconds();
      m = checkTime(m);
      s = checkTime(s);
      timeout_clock.innerHTML = h + ":" + m + ":" + s;
      tc = setTimeout(startTimeoutClock, 500);
    }
    function stopTimeoutClock() {
      clearTimeout(tc);
      timeout_clock.innerHTML = "timeoutClock stopped";
    }
    startTimeoutClock();

    function startIntervalClock() {
      ic = setInterval(
        () => {d = new Date(); interval_clock.innerHTML = d.toLocaleTimeString()},
        1000
      );
    }
    function stopIntervalClock() {
      clearInterval(ic);
      interval_clock.innerHTML = "intervalClock stopped";
    }
    startIntervalClock();
  

    var ctr = document.getElementById("cookie_tests_result");
    var cookie_key = document.getElementById("cookie_key");
    var cookie_value = document.getElementById("cookie_value");

    function cookieGet () {
      ctr.innerHTML += docCookies.getItem(cookie_key.value);
    }
    function cookieSet () {
      if (docCookies.setItem(cookie_key.value,cookie_value.value)) {
        ctr.innerHTML += "Ok, "+cookie_key.value+"="+cookie_value.value+" is set";
      } else {
        ctr.innerHTML += "Problem :(";
      }
    }
    function cookieDel () {
      if (docCookies.removeItem(cookie_key.value)) {
        ctr.innerHTML += "Ok, "+cookie_key.value+" removed";
      } else {
        ctr.innerHTML += "Problem :(";
      }
    }
    function cookieExists () {
      if (docCookies.hasItem(cookie_key.value)) {
        ctr.innerHTML += "Ok, "+cookie_key.value+" exists";
      } else {
        ctr.innerHTML += "No such cookie :(";
      }
    }
    function cookieKeys () {
      console.log(document.cookie)
      ctr.innerHTML += "*** cookies ***";
      docCookies.keys().map((k)=>{
        ctr.innerHTML += k;
      })
      ctr.innerHTML += "***************";
    }

    // cookies reader/writer framework with full unicode support:
    // docCookies.getItem(key)
    // docCookies.setItem(key,val[,exp_seconds,path,domain,secure])
    // docCookies.removeItem(key)
    // docCookies.hasItem(key)
    // docCookies.keys(key[,path,domain])
    var docCookies = {
      getItem: function (sKey) {
        if (!sKey) { return null; }
        return decodeURIComponent(
          document.cookie.replace(
            new RegExp("(?:(?:^|.*;)\\s*" +
            encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") +
            "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1"
          )
        ) || null;
      },
      setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
        // vEnd - max-age in seconds (31536e3 for a year, Infinity for a never-expire)
        // or expires date in GMTString format or as Date object
        // if not, the specified the cookie will expire at the end of the session
        // sPath - must be absolute
        // from where the cookie will be readable. E.g., "/", "/mydir"
        // defaults to the current path of the current document location
        // sDomain -from where the cookie will be readable
        // "example.com", ".example.com" (all subdomains) or "subdomain.example.com"
        // defaults to the host portion of the current document location
        // bSecure -
        // cookie will be transmitted only over secure protocol as https
        if (
          !sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)
        ) { return false; }
        var sExpires = "";
        if (vEnd) {
          switch (vEnd.constructor) {
            case Number:
              sExpires = vEnd === Infinity ?
                "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
              break;
            case String:
              sExpires = "; expires=" + vEnd;
              break;
            case Date:
              sExpires = "; expires=" + vEnd.toUTCString();
              break;
          }
        }
        document.cookie = encodeURIComponent(sKey) + "=" +
          encodeURIComponent(sValue) +
          sExpires +
          (sDomain ? "; domain=" + sDomain : "") +
          (sPath ? "; path=" + sPath : "") +
          (bSecure ? "; secure" : "");
        return true;
      },
      removeItem: function (sKey, sPath, sDomain) {
        if (!this.hasItem(sKey)) { return false; }
        document.cookie = encodeURIComponent(sKey) +
        "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" +
        (sDomain ? "; domain=" + sDomain : "") +
        (sPath ? "; path=" + sPath : "");
        return true;
      },
      hasItem: function (sKey) {
        if (
          !sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)
        ) { return false; }
        return (
          new RegExp("(?:^|;\\s*)" +
          encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") +
          "\\s*\\=")
        ).test(document.cookie);
      },
      keys: function () {
        var aKeys = document.cookie.replace(
          /((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, ""
        ).split(/\s*(?:\=[^;]*)?;\s*/);
        for (var nLen = aKeys.length, nIdx = 0; nIdx < nLen; nIdx++) {
          aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]);
        }
        return aKeys;
      },
      // create a GMTString from a relative time
      maxAgeToGMT: function (nMaxAge) {
        return nMaxAge === Infinity ? "Fri, 31 Dec 9999 23:59:59 GMT" :
        (new Date(nMaxAge * 1e3 + Date.now())).toUTCString();
      }
    };
  

Back to Main Page