// Copyright (c) 2010 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 This file provides a class that can be used to open URLs based * on user interactions. It ensures a consistent behavior when it comes to * holding down Ctrl and Shift while clicking or activating the a link. * * This depends on the {@code chrome.windows} and {@code chrome.tabs} * extensions API. */ cr.define('cr', function() { /** * The kind of link open we want to perform. * @enum {number} */ const LinkKind = { FOREGROUND_TAB: 0, BACKGROUND_TAB: 1, WINDOW: 2, SELF: 3, INCOGNITO: 4 }; /** * This class is used to handle opening of links based on user actions. The * following actions are currently implemented: * * * Press Ctrl and click a link. Or click a link with your middle mouse * button (or mousewheel). Or press Enter while holding Ctrl. * Opens the link in a new tab in the background . * * Press Ctrl+Shift and click a link. Or press Shift and click a link with * your middle mouse button (or mousewheel). Or press Enter while holding * Ctrl+Shift. * Opens the link in a new tab and switches to the newly opened tab. * * Press Shift and click a link. Or press Enter while holding Shift. * Opens the link in a new window. * * On Mac, uses Command instead of Ctrl. * For keyboard support you need to use keydown. * * @param {!LocalStrings} localStrings The local strings object which is used * to localize the warning prompt in case the user tries to open a lot of * links. * @constructor */ function LinkController(localStrings) { this.localStrings_ = localStrings; } LinkController.prototype = { /** * The number of links that can be opened before showing a warning confirm * message. */ warningLimit: 15, /** * The DOM window that we want to open links into in case we are opening * links in the same window. * @type {!Window} */ window: window, /** * This method is used for showing the warning confirm message when the * user is trying to open a lot of links. * @param {number} The number of URLs to open. * @return {string} The message to show the user. */ getWarningMessage: function(count) { return this.localStrings_.getStringF('should_open_all', count); }, /** * Open an URL from a mouse or keyboard event. * @param {string} url The URL to open. * @param {!Event} e The event triggering the opening of the URL. */ openUrlFromEvent: function(url, e) { // We only support keydown Enter and non right click events. if (e.type == 'keydown' && e.keyIdentifier == 'Enter' || e.button != 2) { var kind; var ctrl = cr.isMac && e.metaKey || !cr.isMac && e.ctrlKey; if (e.button == 1 || ctrl) // middle, ctrl or keyboard kind = e.shiftKey ? LinkKind.FOREGROUND_TAB : LinkKind.BACKGROUND_TAB; else // left or keyboard kind = e.shiftKey ? LinkKind.WINDOW : LinkKind.SELF; this.openUrls([url], kind); } }, /** * Opens a URL in a new tab, window or incognito window. * @param {string} url The URL to open. * @param {LinkKind} kind The kind of open we want to do. */ openUrl: function (url, kind) { this.openUrls([url], kind); }, /** * Opens URLs in new tab, window or incognito mode. * @param {!Array.<string>} urls The URLs to open. * @param {LinkKind} kind The kind of open we want to do. */ openUrls: function (urls, kind) { if (urls.length < 1) return; if (urls.length > this.warningLimit) { if (!this.window.confirm(this.getWarningMessage(urls.length))) return; } // Fix '#124' URLs since opening those in a new window does not work. We // prepend the base URL when we encounter those. var base = this.window.location.href.split('#')[0]; urls = urls.map(function(url) { return url[0] == '#' ? base + url : url; }); var incognito = kind == LinkKind.INCOGNITO; if (kind == LinkKind.WINDOW || incognito) { chrome.windows.create({ url: urls, incognito: incognito }); } else if (kind == LinkKind.FOREGROUND_TAB || kind == LinkKind.BACKGROUND_TAB) { urls.forEach(function(url, i) { chrome.tabs.create({ url: url, selected: kind == LinkKind.FOREGROUND_TAB && !i }); }); } else { this.window.location.href = urls[0]; } } }; // Export return { LinkController: LinkController, LinkKind: LinkKind }; });