| Index: chrome/browser/resources/touch_ntp/standalone/standalone_hack.js
|
| diff --git a/chrome/browser/resources/touch_ntp/standalone/standalone_hack.js b/chrome/browser/resources/touch_ntp/standalone/standalone_hack.js
|
| deleted file mode 100644
|
| index 67e7dfda8bfe2a638656528fb347f747625abda8..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/resources/touch_ntp/standalone/standalone_hack.js
|
| +++ /dev/null
|
| @@ -1,562 +0,0 @@
|
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -/**
|
| - * @fileoverview NTP Standalone hack
|
| - * This file contains the code necessary to make the Touch NTP work
|
| - * as a stand-alone application (as opposed to being embedded into chrome).
|
| - * This is useful for rapid development and testing, but does not actually form
|
| - * part of the product.
|
| - *
|
| - * Note that, while the product portion of the touch NTP is designed to work
|
| - * just in the latest version of Chrome, this hack attempts to add some support
|
| - * for working in older browsers to enable testing and demonstration on
|
| - * existing tablet platforms. In particular, this code has been tested to work
|
| - * on Mobile Safari in iOS 4.2. The goal is that the need to support any other
|
| - * browser should not leak out of this file - and so we will hack global JS
|
| - * objects as necessary here to present the illusion of running on the latest
|
| - * version of Chrome.
|
| - */
|
| -
|
| -// Note that this file never gets concatenated and embeded into Chrome, so we
|
| -// can enable strict mode for the whole file just like normal.
|
| -'use strict';
|
| -
|
| -
|
| -/**
|
| - * For non-Chrome browsers, create a dummy chrome object
|
| - */
|
| -if (!window.chrome) {
|
| - var chrome = {};
|
| -}
|
| -
|
| -
|
| -/**
|
| - * A replacement chrome.send method that supplies static data for the
|
| - * key APIs used by the NTP.
|
| - *
|
| - * Note that the real chrome object also supplies data for most-viewed and
|
| - * recently-closed pages, but the tangent NTP doesn't use that data so we
|
| - * don't bother simulating it here.
|
| - *
|
| - * We create this object by applying an anonymous function so that we can have
|
| - * local variables (avoid polluting the global object)
|
| - */
|
| -chrome.send = (function() {
|
| - var apps = [{
|
| - app_launch_index: 2,
|
| - description: 'The prickly puzzle game where popping balloons has ' +
|
| - 'never been so much fun!',
|
| - icon_big: 'standalone/poppit-icon.png',
|
| - icon_small: 'standalone/poppit-favicon.png',
|
| - id: 'mcbkbpnkkkipelfledbfocopglifcfmi',
|
| - launch_container: 2,
|
| - launch_type: 1,
|
| - url: 'http://poppit.pogo.com/hd/PoppitHD.html',
|
| - title: 'Poppit',
|
| - options_url: ''
|
| - },
|
| - {
|
| - app_launch_index: 1,
|
| - description: 'Fast, searchable email with less spam.',
|
| - icon_big: 'standalone/gmail-icon.png',
|
| - icon_small: 'standalone/gmail-favicon.png',
|
| - id: 'pjkljhegncpnkpknbcohdijeoejaedia',
|
| - launch_container: 2,
|
| - launch_type: 1,
|
| - url: 'https://mail.google.com/',
|
| - title: 'Gmail',
|
| - options_url: 'https://mail.google.com/mail/#settings'
|
| - },
|
| - {
|
| - app_launch_index: 3,
|
| - description: 'Read over 3 million Google eBooks on the web.',
|
| - icon_big: 'standalone/googlebooks-icon.png',
|
| - icon_small: 'standalone/googlebooks-favicon.png',
|
| - id: 'mmimngoggfoobjdlefbcabngfnmieonb',
|
| - launch_container: 2,
|
| - launch_type: 1,
|
| - url: 'http://books.google.com/ebooks?source=chrome-app',
|
| - title: 'Google Books',
|
| - options_url: ''
|
| - },
|
| - {
|
| - app_launch_index: 4,
|
| - description: 'Find local business information, directions, and ' +
|
| - 'street-level imagery around the world with Google Maps.',
|
| - icon_big: 'standalone/googlemaps-icon.png',
|
| - icon_small: 'standalone/googlemaps-favicon.png',
|
| - id: 'lneaknkopdijkpnocmklfnjbeapigfbh',
|
| - launch_container: 2,
|
| - launch_type: 1,
|
| - url: 'http://maps.google.com/',
|
| - title: 'Google Maps',
|
| - options_url: ''
|
| - },
|
| - {
|
| - app_launch_index: 5,
|
| - description: 'Create the longest path possible and challenge your ' +
|
| - 'friends in the game of Entanglement.',
|
| - icon_big: 'standalone/entaglement-icon.png',
|
| - id: 'aciahcmjmecflokailenpkdchphgkefd',
|
| - launch_container: 2,
|
| - launch_type: 1,
|
| - url: 'http://entanglement.gopherwoodstudios.com/',
|
| - title: 'Entanglement',
|
| - options_url: ''
|
| - },
|
| - {
|
| - title: 'NYTimes',
|
| - app_launch_index: 6,
|
| - description: 'The New York Times App for the Chrome Web Store.',
|
| - icon_big: 'standalone/nytimes-icon.png',
|
| - id: 'ecmphppfkcfflgglcokcbdkofpfegoel',
|
| - launch_container: 2,
|
| - launch_type: 1,
|
| - url: 'http://www.nytimes.com/chrome/',
|
| - options_url: '',
|
| - page_index: 2
|
| - },
|
| - {
|
| - app_launch_index: 7,
|
| - description: 'The world\'s most popular online video community.',
|
| - id: 'blpcfgokakmgnkcojhhkbfbldkacnbeo',
|
| - icon_big: 'standalone/youtube-icon.png',
|
| - launch_container: 2,
|
| - launch_type: 1,
|
| - url: 'http://www.youtube.com/',
|
| - title: 'YouTube',
|
| - options_url: '',
|
| - page_index: 3
|
| - }];
|
| -
|
| - // For testing
|
| - apps = spamApps(apps);
|
| -
|
| - /**
|
| - * Invoke the getAppsCallback function with a snapshot of the current app
|
| - * database.
|
| - */
|
| - function sendGetAppsCallback()
|
| - {
|
| - // We don't want to hand out our array directly because the NTP will
|
| - // assume it owns the array and is free to modify it. For now we make a
|
| - // one-level deep copy of the array (since cloning the whole thing is
|
| - // more work and unnecessary at the moment).
|
| - var appsData = {
|
| - showPromo: false,
|
| - showLauncher: true,
|
| - apps: apps.slice(0)
|
| - };
|
| - getAppsCallback(appsData);
|
| - }
|
| -
|
| - /**
|
| - * To make testing real-world scenarios easier, this expands our list of
|
| - * apps by duplicating them a number of times
|
| - */
|
| - function spamApps(apps)
|
| - {
|
| - // Create an object that extends another object
|
| - // This is an easy/efficient way to make slightly modified copies of our
|
| - // app objects without having to do a deep copy
|
| - function createObject(proto) {
|
| - /** @constructor */
|
| - var F = function() {};
|
| - F.prototype = proto;
|
| - return new F();
|
| - }
|
| -
|
| - var newApps = [];
|
| - var pages = Math.floor(Math.random() * 8) + 1;
|
| - var idx = 1;
|
| - for (var p = 0; p < pages; p++) {
|
| - var count = Math.floor(Math.random() * 18) + 1;
|
| - for (var a = 0; a < count; a++) {
|
| - var i = Math.floor(Math.random() * apps.length);
|
| - var newApp = createObject(apps[i]);
|
| - newApp.page_index = p;
|
| - newApp.app_launch_index = idx;
|
| - // Uniqify the ID
|
| - newApp.id = apps[i].id + '-' + idx;
|
| - idx++;
|
| - newApps.push(newApp);
|
| - }
|
| - }
|
| - return newApps;
|
| - }
|
| -
|
| - /**
|
| - * Like Array.prototype.indexOf but calls a predicate to test for match
|
| - *
|
| - * @param {Array} array The array to search.
|
| - * @param {function(Object): boolean} predicate The function to invoke on
|
| - * each element.
|
| - * @return {number} First index at which predicate returned true, or -1.
|
| - */
|
| - function indexOfPred(array, predicate) {
|
| - for (var i = 0; i < array.length; i++) {
|
| - if (predicate(array[i]))
|
| - return i;
|
| - }
|
| - return -1;
|
| - }
|
| -
|
| - /**
|
| - * Get index into apps of an application object
|
| - * Requires the specified app to be present
|
| - *
|
| - * @param {string} id The ID of the application to locate.
|
| - * @return {number} The index in apps for an object with the specified ID.
|
| - */
|
| - function getAppIndex(id) {
|
| - var i = indexOfPred(apps, function(e) { return e.id === id;});
|
| - if (i == -1)
|
| - alert('Error: got unexpected App ID');
|
| - return i;
|
| - }
|
| -
|
| - /**
|
| - * Get an application object given the application ID
|
| - * Requires
|
| - * @param {string} id The application ID to search for.
|
| - * @return {Object} The corresponding application object.
|
| - */
|
| - function getApp(id) {
|
| - return apps[getAppIndex(id)];
|
| - }
|
| -
|
| - /**
|
| - * Simlulate the launching of an application
|
| - *
|
| - * @param {string} id The ID of the application to launch.
|
| - */
|
| - function launchApp(id) {
|
| - // Note that we don't do anything with the icon location.
|
| - // That's used by Chrome only on Windows to animate the icon during
|
| - // launch.
|
| - var app = getApp(id);
|
| - switch (parseInt(app.launch_type, 10)) {
|
| - case 0: // pinned
|
| - case 1: // regular
|
| - // Replace the current tab with the app.
|
| - // Pinned seems to omit the tab title, but I doubt it's
|
| - // possible for us to do that here
|
| - window.location = (app.url);
|
| - break;
|
| -
|
| - case 2: // fullscreen
|
| - case 3: // window
|
| - // attempt to launch in a new window
|
| - window.close();
|
| - window.open(app.url, app.title,
|
| - 'resizable=yes,scrollbars=yes,status=yes');
|
| - break;
|
| -
|
| - default:
|
| - alert('Unexpected launch type: ' + app.launch_type);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Simulate uninstall of an app
|
| - * @param {string} id The ID of the application to uninstall.
|
| - */
|
| - function uninstallApp(id) {
|
| - var i = getAppIndex(id);
|
| - // This confirmation dialog doesn't look exactly the same as the
|
| - // standard NTP one, but it's close enough.
|
| - if (window.confirm('Uninstall \"' + apps[i].title + '\"?')) {
|
| - apps.splice(i, 1);
|
| - sendGetAppsCallback();
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Update the app_launch_index of all apps
|
| - * @param {Array.<string>} appIds All app IDs in their desired order.
|
| - */
|
| - function reorderApps(movedAppId, appIds) {
|
| - assert(apps.length == appIds.length, 'Expected all apps in reorderApps');
|
| -
|
| - // Clear the launch indicies so we can easily verify no dups
|
| - apps.forEach(function(a) {
|
| - a.app_launch_index = -1;
|
| - });
|
| -
|
| - for (var i = 0; i < appIds.length; i++) {
|
| - var a = getApp(appIds[i]);
|
| - assert(a.app_launch_index == -1,
|
| - 'Found duplicate appId in reorderApps');
|
| - a.app_launch_index = i;
|
| - }
|
| - sendGetAppsCallback();
|
| - }
|
| -
|
| - /**
|
| - * Update the page number of an app
|
| - * @param {string} id The ID of the application to move.
|
| - * @param {number} page The page index to place the app.
|
| - */
|
| - function setPageIndex(id, page) {
|
| - var app = getApp(id);
|
| - app.page_index = page;
|
| - }
|
| -
|
| - // The 'send' function
|
| - /**
|
| - * The chrome server communication entrypoint.
|
| - *
|
| - * @param {string} command Name of the command to send.
|
| - * @param {Array} args Array of command-specific arguments.
|
| - */
|
| - return function(command, args) {
|
| - // Chrome API is async
|
| - window.setTimeout(function() {
|
| - switch (command) {
|
| - // called to populate the list of applications
|
| - case 'getApps':
|
| - sendGetAppsCallback();
|
| - break;
|
| -
|
| - // Called when an app is launched
|
| - // Ignore additional arguments - they've been changing over time and
|
| - // we don't use them in our NTP anyway.
|
| - case 'launchApp':
|
| - launchApp(args[0]);
|
| - break;
|
| -
|
| - // Called when an app is uninstalled
|
| - case 'uninstallApp':
|
| - uninstallApp(args[0]);
|
| - break;
|
| -
|
| - // Called when an app is repositioned in the touch NTP
|
| - case 'reorderApps':
|
| - reorderApps(args[0], args[1]);
|
| - break;
|
| -
|
| - // Called when an app is moved to a different page
|
| - case 'setPageIndex':
|
| - setPageIndex(args[0], parseInt(args[1], 10));
|
| - break;
|
| -
|
| - default:
|
| - throw new Error('Unexpected chrome command: ' + command);
|
| - break;
|
| - }
|
| - }, 0);
|
| - };
|
| -})();
|
| -
|
| -/* A static templateData with english resources */
|
| -var templateData = {
|
| - title: 'Standalone New Tab',
|
| - web_store_title: 'Web Store',
|
| - web_store_url: 'https://chrome.google.com/webstore?hl=en-US'
|
| -};
|
| -
|
| -/* Hook construction of chrome://theme URLs */
|
| -function themeUrlMapper(resourceName) {
|
| - if (resourceName == 'IDR_WEBSTORE_ICON') {
|
| - return 'standalone/webstore_icon.png';
|
| - }
|
| - return undefined;
|
| -}
|
| -
|
| -/*
|
| - * On iOS we need a hack to avoid spurious click events
|
| - * In particular, if the user delays briefly between first touching and starting
|
| - * to drag, when the user releases a click event will be generated.
|
| - * Note that this seems to happen regardless of whether we do preventDefault on
|
| - * touchmove events.
|
| - */
|
| -if (/iPhone|iPod|iPad/.test(navigator.userAgent) &&
|
| - !(/Chrome/.test(navigator.userAgent))) {
|
| - // We have a real iOS device (no a ChromeOS device pretending to be iOS)
|
| - (function() {
|
| - // True if a gesture is occuring that should cause clicks to be swallowed
|
| - var gestureActive = false;
|
| -
|
| - // The position a touch was last started
|
| - var lastTouchStartPosition;
|
| -
|
| - // Distance which a touch needs to move to be considered a drag
|
| - var DRAG_DISTANCE = 3;
|
| -
|
| - document.addEventListener('touchstart', function(event) {
|
| - lastTouchStartPosition = {
|
| - x: event.touches[0].clientX,
|
| - y: event.touches[0].clientY
|
| - };
|
| - // A touchstart ALWAYS preceeds a click (valid or not), so cancel any
|
| - // outstanding gesture. Also, any multi-touch is a gesture that should
|
| - // prevent clicks.
|
| - gestureActive = event.touches.length > 1;
|
| - }, true);
|
| -
|
| - document.addEventListener('touchmove', function(event) {
|
| - // When we see a move, measure the distance from the last touchStart
|
| - // If this is a multi-touch then the work here is irrelevant
|
| - // (gestureActive is already true)
|
| - var t = event.touches[0];
|
| - if (Math.abs(t.clientX - lastTouchStartPosition.x) > DRAG_DISTANCE ||
|
| - Math.abs(t.clientY - lastTouchStartPosition.y) > DRAG_DISTANCE) {
|
| - gestureActive = true;
|
| - }
|
| - }, true);
|
| -
|
| - document.addEventListener('click', function(event) {
|
| - // If we got here without gestureActive being set then it means we had
|
| - // a touchStart without any real dragging before touchEnd - we can allow
|
| - // the click to proceed.
|
| - if (gestureActive) {
|
| - event.preventDefault();
|
| - event.stopPropagation();
|
| - }
|
| - }, true);
|
| - })();
|
| -}
|
| -
|
| -/* Hack to add Element.classList to older browsers that don't yet support it.
|
| - From https://developer.mozilla.org/en/DOM/element.classList.
|
| -*/
|
| -if (typeof Element !== 'undefined' &&
|
| - !Element.prototype.hasOwnProperty('classList')) {
|
| - (function() {
|
| - var classListProp = 'classList',
|
| - protoProp = 'prototype',
|
| - elemCtrProto = Element[protoProp],
|
| - objCtr = Object,
|
| - strTrim = String[protoProp].trim || function() {
|
| - return this.replace(/^\s+|\s+$/g, '');
|
| - },
|
| - arrIndexOf = Array[protoProp].indexOf || function(item) {
|
| - for (var i = 0, len = this.length; i < len; i++) {
|
| - if (i in this && this[i] === item) {
|
| - return i;
|
| - }
|
| - }
|
| - return -1;
|
| - },
|
| - // Vendors: please allow content code to instantiate DOMExceptions
|
| - /** @constructor */
|
| - DOMEx = function(type, message) {
|
| - this.name = type;
|
| - this.code = DOMException[type];
|
| - this.message = message;
|
| - },
|
| - checkTokenAndGetIndex = function(classList, token) {
|
| - if (token === '') {
|
| - throw new DOMEx(
|
| - 'SYNTAX_ERR',
|
| - 'An invalid or illegal string was specified'
|
| - );
|
| - }
|
| - if (/\s/.test(token)) {
|
| - throw new DOMEx(
|
| - 'INVALID_CHARACTER_ERR',
|
| - 'String contains an invalid character'
|
| - );
|
| - }
|
| - return arrIndexOf.call(classList, token);
|
| - },
|
| - /** @constructor
|
| - * @extends {Array} */
|
| - ClassList = function(elem) {
|
| - var trimmedClasses = strTrim.call(elem.className),
|
| - classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [];
|
| -
|
| - for (var i = 0, len = classes.length; i < len; i++) {
|
| - this.push(classes[i]);
|
| - }
|
| - this._updateClassName = function() {
|
| - elem.className = this.toString();
|
| - };
|
| - },
|
| - classListProto = ClassList[protoProp] = [],
|
| - classListGetter = function() {
|
| - return new ClassList(this);
|
| - };
|
| -
|
| - // Most DOMException implementations don't allow calling DOMException's
|
| - // toString() on non-DOMExceptions. Error's toString() is sufficient here.
|
| - DOMEx[protoProp] = Error[protoProp];
|
| - classListProto.item = function(i) {
|
| - return this[i] || null;
|
| - };
|
| - classListProto.contains = function(token) {
|
| - token += '';
|
| - return checkTokenAndGetIndex(this, token) !== -1;
|
| - };
|
| - classListProto.add = function(token) {
|
| - token += '';
|
| - if (checkTokenAndGetIndex(this, token) === -1) {
|
| - this.push(token);
|
| - this._updateClassName();
|
| - }
|
| - };
|
| - classListProto.remove = function(token) {
|
| - token += '';
|
| - var index = checkTokenAndGetIndex(this, token);
|
| - if (index !== -1) {
|
| - this.splice(index, 1);
|
| - this._updateClassName();
|
| - }
|
| - };
|
| - classListProto.toggle = function(token) {
|
| - token += '';
|
| - if (checkTokenAndGetIndex(this, token) === -1) {
|
| - this.add(token);
|
| - } else {
|
| - this.remove(token);
|
| - }
|
| - };
|
| - classListProto.toString = function() {
|
| - return this.join(' ');
|
| - };
|
| -
|
| - if (objCtr.defineProperty) {
|
| - var classListDescriptor = {
|
| - get: classListGetter,
|
| - enumerable: true,
|
| - configurable: true
|
| - };
|
| - objCtr.defineProperty(elemCtrProto, classListProp, classListDescriptor);
|
| - } else if (objCtr[protoProp].__defineGetter__) {
|
| - elemCtrProto.__defineGetter__(classListProp, classListGetter);
|
| - }
|
| - }());
|
| -}
|
| -
|
| -/* Hack to add Function.bind to older browsers that don't yet support it. From:
|
| - https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
|
| -*/
|
| -if (!Function.prototype.bind) {
|
| - /**
|
| - * @param {Object} selfObj Specifies the object which |this| should
|
| - * point to when the function is run. If the value is null or undefined,
|
| - * it will default to the global object.
|
| - * @param {...*} var_args Additional arguments that are partially
|
| - * applied to the function.
|
| - * @return {!Function} A partially-applied form of the function bind() was
|
| - * invoked as a method of.
|
| - * @suppress {duplicate}
|
| - */
|
| - Function.prototype.bind = function(selfObj, var_args) {
|
| - var slice = [].slice,
|
| - args = slice.call(arguments, 1),
|
| - self = this,
|
| - /** @constructor */
|
| - nop = function() {},
|
| - bound = function() {
|
| - return self.apply(this instanceof nop ? this : (selfObj || {}),
|
| - args.concat(slice.call(arguments)));
|
| - };
|
| - nop.prototype = self.prototype;
|
| - bound.prototype = new nop();
|
| - return bound;
|
| - };
|
| -}
|
| -
|
|
|