frame.js revision f2477e01787aa58f445919b809d89e252beef54f
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 iframeEl = null;
17var isChrome = /Chrome\/([^\s]+)/.test(navigator.userAgent);
18var isMobile = /Mobi/.test(navigator.userAgent);
19var hasPnacl = navigator.mimeTypes['application/x-pnacl'] !== undefined;
20
21if (isChrome && !isMobile) {
22  if (hasPnacl) {
23    makeExampleList();
24    window.onpopstate = function(popState) {
25      if (popState.state == null) {
26        updateViewFromLocation();
27      } else {
28        var exampleName = popState.state;
29        loadExample(popState.state);
30      }
31    }
32  } else {
33    // Older version of Chrome?
34    showOldChromeErrorMessage();
35  }
36} else {
37  // Not Chrome, or is mobile Chrome.
38  showNotChromeErrorMessage();
39}
40
41function makeExampleList() {
42  var listEl = document.querySelector('nav ul');
43  for (var i = 0; i < examples.length; ++i) {
44    var example = examples[i];
45
46    // Populate exampleMap
47    exampleMap[example.name] = example;
48
49    // Create li
50    var listItemEl = document.createElement('li');
51    var anchorEl = document.createElement('a');
52    listItemEl.setAttribute('id', example.name);
53    anchorEl.setAttribute('href', getExampleUrl(example.name));
54    anchorEl.setAttribute('target', 'content');
55    anchorEl.textContent = example.text;
56
57    // Listen for clicks and update the nav
58    anchorEl.addEventListener('click', onLinkClick.bind(example), false);
59
60    listItemEl.appendChild(anchorEl);
61    listEl.appendChild(listItemEl);
62  }
63}
64
65function getExampleUrl(exampleName) {
66  return '/static/' + exampleName + '/index.html';
67}
68
69function onLinkClick(evt) {
70  evt.preventDefault();
71  pushState(this.name);
72  loadExample(this.name);
73}
74
75function updateViewFromLocation() {
76  // Get the location's path.
77  var anchorEl = document.createElement('a');
78  anchorEl.href = location.href;
79  var pathname = anchorEl.pathname;
80
81  // Load the correct page, based on the demo name.
82  var matches = pathname.match(/demo(?:\/(.*))?$/);
83  var iframeUrl = null;
84  if (matches) {
85    var matchedExample = matches[1];
86    // Strip trailing slash, if any.
87    if (matchedExample && matchedExample.slice(-1) === '/') {
88      matchedExample = matchedExample.slice(0, -1);
89    }
90
91    if (matchedExample in exampleMap) {
92      replaceState(matchedExample);
93      loadExample(matchedExample);
94    } else {
95      replaceHomeState();
96      createHomeIframe();
97    }
98  }
99}
100
101function loadExample(exampleName) {
102  updateTitle(exampleName);
103  createExampleIframe(exampleName);
104  updateNav(exampleName);
105}
106
107function updateNav(exampleName) {
108  var links = document.querySelectorAll('li a');
109  for (var l = 0; l < links.length; l++) {
110    links[l].classList.remove('active');
111  }
112
113  if (exampleName != 'home')
114    document.querySelector('li#' + exampleName + ' a').classList.add('active');
115}
116
117function updateTitle(exampleName) {
118  var title = 'PNaCl Demos';
119  if (exampleName != 'home') {
120    title += ': ' + exampleMap[exampleName].text;
121  }
122  document.title = title;
123}
124
125function createExampleIframe(exampleName) {
126  createIframe(getExampleUrl(exampleName));
127}
128
129function createHomeIframe() {
130  createIframe('/static/home/index.html');
131}
132
133function createIframe(src) {
134  var oldIframeEl = iframeEl;
135
136  iframeEl = document.createElement('iframe');
137  iframeEl.setAttribute('frameborder', '0');
138  iframeEl.setAttribute('width', '100%');
139  iframeEl.setAttribute('height', '100%');
140  iframeEl.src = src;
141  iframeEl.setAttribute('hidden');
142  iframeEl.onload = function() {
143    if (oldIframeEl)
144      oldIframeEl.parentNode.removeChild(oldIframeEl);
145    iframeEl.removeAttribute('hidden');
146  }
147  document.querySelector('section').appendChild(iframeEl);
148}
149
150function pushState(exampleName) {
151  window.history.pushState(exampleName, '', '/demo/' + exampleName);
152}
153
154function replaceState(exampleName) {
155  window.history.replaceState(exampleName, '', '/demo/' + exampleName);
156}
157
158function replaceHomeState() {
159  window.history.replaceState('home', '', '/demo');
160}
161
162function showOldChromeErrorMessage() {
163  document.getElementById('old-chrome').removeAttribute('hidden');
164}
165
166function showNotChromeErrorMessage() {
167  document.getElementById('not-chrome').removeAttribute('hidden');
168}
169