frame.js revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5var examples = [
6  {name: 'bullet', text: 'Bullet Physics'},
7  {name: 'earth', text: 'Raycasted Earth'},
8  {name: 'lua', text: 'Lua Interpreter'},
9  {name: 'life', text: 'Game of Life'},
10  {name: 'voronoi', text: 'Voronoi Simulation'},
11  {name: 'smoothlife', text: 'SmoothLife'},
12  {name: 'cube', text: 'Rotating Cube'},
13];
14var exampleMap = {};  // Created below.
15
16var isChrome = /Chrome\/([^\s]+)/.test(navigator.userAgent);
17var isMobile = /Mobi/.test(navigator.userAgent);
18var hasPnacl = navigator.mimeTypes['application/x-pnacl'] !== undefined;
19
20if (isChrome && !isMobile) {
21  if (hasPnacl) {
22    makeExampleList();
23    if (history.state == null) {
24      updateViewFromLocation();
25    }
26
27    window.onpopstate = function(event) {
28      var exampleName = event.state;
29      loadExample(exampleName);
30    }
31  } else {
32    // Older version of Chrome?
33    showOldChromeErrorMessage();
34  }
35} else {
36  // Not Chrome, or is mobile Chrome.
37  showNotChromeErrorMessage();
38}
39
40function makeExampleList() {
41  var listEl = document.querySelector('nav ul');
42  for (var i = 0; i < examples.length; ++i) {
43    var example = examples[i];
44
45    // Populate exampleMap
46    exampleMap[example.name] = example;
47
48    // Create li
49    var listItemEl = document.createElement('li');
50    var anchorEl = document.createElement('a');
51    listItemEl.setAttribute('id', example.name);
52    anchorEl.setAttribute('href', getExampleUrl(example.name));
53    anchorEl.setAttribute('target', 'content');
54    anchorEl.textContent = example.text;
55
56    // Listen for clicks and update the nav
57    anchorEl.addEventListener('click', onLinkClick.bind(example), false);
58
59    listItemEl.appendChild(anchorEl);
60    listEl.appendChild(listItemEl);
61  }
62}
63
64function getExampleUrl(exampleName) {
65  return '/static/' + exampleName + '/index.html';
66}
67
68function onLinkClick(evt) {
69  evt.preventDefault();
70  pushState(this.name);
71  loadExample(this.name);
72}
73
74function updateViewFromLocation() {
75  // Get the location's path.
76  var anchorEl = document.createElement('a');
77  anchorEl.href = location.href;
78  var pathname = anchorEl.pathname;
79
80  // Load the correct page, based on the demo name.
81  var matches = pathname.match(/demo(?:\/(.*))?$/);
82  var iframeUrl = null;
83  if (matches) {
84    var matchedExample = matches[1];
85    // Strip trailing slash, if any.
86    if (matchedExample && matchedExample.slice(-1) === '/') {
87      matchedExample = matchedExample.slice(0, -1);
88    }
89
90    if (matchedExample in exampleMap) {
91      replaceState(matchedExample);
92      loadExample(matchedExample);
93    } else {
94      replaceHomeState();
95      createHomeIframe();
96    }
97  }
98}
99
100function loadExample(exampleName) {
101  updateTitle(exampleName);
102  createExampleIframe(exampleName);
103  updateNav(exampleName);
104}
105
106function updateNav(exampleName) {
107  var links = document.querySelectorAll('li a');
108  for (var l = 0; l < links.length; l++) {
109    links[l].classList.remove('active');
110  }
111
112  if (exampleName != 'home')
113    document.querySelector('li#' + exampleName + ' a').classList.add('active');
114}
115
116function updateTitle(exampleName) {
117  var title = 'PNaCl Demos';
118  if (exampleName != 'home') {
119    title += ': ' + exampleMap[exampleName].text;
120  }
121  document.title = title;
122}
123
124function createExampleIframe(exampleName) {
125  createIframe(getExampleUrl(exampleName));
126}
127
128function createHomeIframe() {
129  createIframe('/static/home/index.html');
130}
131
132function createIframe(src) {
133  var iframeEl = document.querySelector('iframe');
134  if (iframeEl === null) {
135    iframeEl = document.createElement('iframe');
136    iframeEl.setAttribute('frameborder', '0');
137    iframeEl.setAttribute('width', '100%');
138    iframeEl.setAttribute('height', '100%');
139    iframeEl.src = src;
140    document.querySelector('section').appendChild(iframeEl);
141  } else {
142    iframeEl.contentDocument.location.replace(src);
143  }
144}
145
146function pushState(exampleName) {
147  window.history.pushState(exampleName, '', '/demo/' + exampleName);
148}
149
150function replaceState(exampleName) {
151  window.history.replaceState(exampleName, '', '/demo/' + exampleName);
152}
153
154function replaceHomeState() {
155  window.history.replaceState('home', '', '/demo');
156}
157
158function showOldChromeErrorMessage() {
159  document.getElementById('old-chrome').removeAttribute('hidden');
160}
161
162function showNotChromeErrorMessage() {
163  document.getElementById('not-chrome').removeAttribute('hidden');
164}
165