diff options
author | feldstein@chromium.org <feldstein@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-28 23:52:56 +0000 |
---|---|---|
committer | feldstein@chromium.org <feldstein@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-28 23:52:56 +0000 |
commit | fbd17cf5288dec78851ada15fadfda0563419833 (patch) | |
tree | fedf6d2264d10d9e5d6c9db6c188ae13b02b6d4b /chrome/browser/resources/bookmark_manager/js | |
parent | de3784727a0656f23468e3caa1cdf4ad894a5d15 (diff) | |
download | chromium_src-fbd17cf5288dec78851ada15fadfda0563419833.zip chromium_src-fbd17cf5288dec78851ada15fadfda0563419833.tar.gz chromium_src-fbd17cf5288dec78851ada15fadfda0563419833.tar.bz2 |
Rework of the shared resources patch for checkin
Implement shared resources and use them in bookmark manager
I had an issue with git when moving files so i had to create a new patch to
delete/readd them here. See code review 1564034. This is just for
trybots/checkins.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/1694019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45885 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/resources/bookmark_manager/js')
23 files changed, 0 insertions, 4787 deletions
diff --git a/chrome/browser/resources/bookmark_manager/js/cr.js b/chrome/browser/resources/bookmark_manager/js/cr.js deleted file mode 100644 index 9de94da..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr.js +++ /dev/null @@ -1,314 +0,0 @@ -// 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. - -const cr = (function() { - - /** - * Whether we are using a Mac or not. - * @type {boolean} - */ - const isMac = /Mac/.test(navigator.platform); - - /** - * Builds an object structure for the provided namespace path, - * ensuring that names that already exist are not overwritten. For - * example: - * "a.b.c" -> a = {};a.b={};a.b.c={}; - * @param {string} name Name of the object that this file defines. - * @param {*=} opt_object The object to expose at the end of the path. - * @param {Object=} opt_objectToExportTo The object to add the path to; - * default is {@code window}. - * @private - */ - function exportPath(name, opt_object, opt_objectToExportTo) { - var parts = name.split('.'); - var cur = opt_objectToExportTo || window /* global */; - - for (var part; parts.length && (part = parts.shift());) { - if (!parts.length && opt_object !== undefined) { - // last part and we have an object; use it - cur[part] = opt_object; - } else if (part in cur) { - cur = cur[part]; - } else { - cur = cur[part] = {}; - } - } - return cur; - }; - - /** - * Fires a property change event on the target. - * @param {EventTarget} target The target to dispatch the event on. - * @param {string} propertyName The name of the property that changed. - * @param {*} newValue The new value for the property. - * @param {*} oldValue The old value for the property. - */ - function dispatchPropertyChange(target, propertyName, newValue, oldValue) { - // TODO(arv): Depending on cr.Event here is a bit ugly. - var e = new cr.Event(propertyName + 'Change'); - e.propertyName = propertyName; - e.newValue = newValue; - e.oldValue = oldValue; - target.dispatchEvent(e); - } - - /** - * The kind of property to define in {@code defineProperty}. - * @enum {number} - */ - const PropertyKind = { - /** - * Plain old JS property where the backing data is stored as a "private" - * field on the object. - */ - JS: 'js', - - /** - * The property backing data is stored as an attribute on an element. - */ - ATTR: 'attr', - - /** - * The property backing data is stored as an attribute on an element. If the - * element has the attribute then the value is true. - */ - BOOL_ATTR: 'boolAttr' - }; - - /** - * Helper function for defineProperty that returns the getter to use for the - * property. - * @param {string} name - * @param {cr.PropertyKind} kind - * @param {*} defaultValue The default value. This is only used for the ATTR - * kind. - * @return {function():*} The getter for the property. - */ - function getGetter(name, kind, defaultValue) { - switch (kind) { - case PropertyKind.JS: - var privateName = name + '_'; - return function() { - return this[privateName]; - }; - case PropertyKind.ATTR: - // For attr with default value we return the default value if the - // element is missing the attribute. - if (defaultValue == undefined) { - return function() { - return this.getAttribute(name); - }; - } else { - return function() { - // WebKit uses null for non existant attributes. - var value = this.getAttribute(name); - return value !== null ? value : defaultValue; - }; - } - case PropertyKind.BOOL_ATTR: - // Boolean attributes don't support default values. - return function() { - return this.hasAttribute(name); - }; - } - } - - /** - * Helper function for defineProperty that returns the setter of the right - * kind. - * @param {string} name The name of the property we are defining the setter - * for. - * @param {cr.PropertyKind} kind The kind of property we are getting the - * setter for. - * @return {function(*):void} The function to use as a setter. - */ - function getSetter(name, kind) { - switch (kind) { - case PropertyKind.JS: - var privateName = name + '_'; - return function(value) { - var oldValue = this[privateName]; - if (value !== oldValue) { - this[privateName] = value; - dispatchPropertyChange(this, name, value, oldValue); - } - }; - - case PropertyKind.ATTR: - return function(value) { - var oldValue = this[name]; - if (value !== oldValue) { - this.setAttribute(name, value); - dispatchPropertyChange(this, name, value, oldValue); - } - }; - - case PropertyKind.BOOL_ATTR: - return function(value) { - var oldValue = this[name]; - if (value !== oldValue) { - if (value) - this.setAttribute(name, name); - else - this.removeAttribute(name); - dispatchPropertyChange(this, name, value, oldValue); - } - }; - } - } - - /** - * Defines a property on an object. When the setter changes the value a - * property change event with the type {@code name + 'Change'} is fired. - * @param {!Object} The object to define the property for. - * @param {string} The name of the property. - * @param {cr.PropertyKind=} opt_kind What kind of underlying storage to use. - * @param {*} opt_defaultValue The default value. - */ - function defineProperty(obj, name, opt_kind, opt_default) { - if (typeof obj == 'function') - obj = obj.prototype; - - var kind = opt_kind || PropertyKind.JS; - - if (!obj.__lookupGetter__(name)) { - // For js properties we set the default value on the prototype. - if (kind == PropertyKind.JS && arguments.length > 3) { - var privateName = name + '_'; - obj[privateName] = opt_default; - } - obj.__defineGetter__(name, getGetter(name, kind, opt_default)); - } - - if (!obj.__lookupSetter__(name)) { - obj.__defineSetter__(name, getSetter(name, kind)); - } - } - - /** - * Counter for use with createUid - */ - var uidCounter = 1; - - /** - * @return {number} A new unique ID. - */ - function createUid() { - return uidCounter++; - } - - /** - * Returns a unique ID for the item. This mutates the item so it needs to be - * an object - * @param {!Object} item The item to get the unique ID for. - * @return {number} The unique ID for the item. - */ - function getUid(item) { - if (item.hasOwnProperty('uid')) - return item.uid; - return item.uid = createUid(); - } - - /** - * Partially applies this function to a particular 'this object' and zero or - * more arguments. The result is a new function with some arguments of the - * first function pre-filled and the value of |this| 'pre-specified'. - * - * Remaining arguments specified at call-time are appended to the pre- - * specified ones. - * - * Usage: - * <pre>var barMethBound = bind(myFunction, myObj, 'arg1', 'arg2'); - * barMethBound('arg3', 'arg4');</pre> - * - * @param {Function} fn A function to partially apply. - * @param {Object|undefined} 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. - */ - function bind(fn, selfObj, var_args) { - var boundArgs = Array.prototype.slice.call(arguments, 2); - return function() { - var args = Array.prototype.slice.call(arguments); - args.unshift.apply(args, boundArgs); - return fn.apply(selfObj, args); - } - } - - /** - * Dispatches a simple event on an event target. - * @param {!EventTarget} target The event target to dispatch the event on. - * @param {string} type The type of the event. - * @param {boolean=} opt_bubbles Whether the event bubbles or not. - * @param {boolean=} opt_cancelable Whether the default action of the event - * can be prevented. - * @return {boolean} If any of the listeners called {@code preventDefault} - * during the dispatch this will return false. - */ - function dispatchSimpleEvent(target, type, opt_bubbles, opt_cancelable) { - var e = new cr.Event(type, opt_bubbles, opt_cancelable); - return target.dispatchEvent(e); - } - - /** - * @param {string} name - * @param {!Function} fun - */ - function define(name, fun) { - var obj = exportPath(name); - var exports = fun(); - for (var key in exports) { - obj[key] = exports[key]; - } - } - - /** - * Document used for various document related operations. - * @type {!Document} - */ - var doc = document; - - - /** - * Allows you to run func in the context of a different document. - * @param {!Document} document The document to use. - * @param {function():*} func The function to call. - */ - function withDoc(document, func) { - var oldDoc = doc; - doc = document; - try { - func(); - } finally { - doc = oldDoc; - } - } - - return { - isMac: isMac, - define: define, - defineProperty: defineProperty, - PropertyKind: PropertyKind, - createUid: createUid, - getUid: getUid, - bind: bind, - dispatchSimpleEvent: dispatchSimpleEvent, - dispatchPropertyChange: dispatchPropertyChange, - - /** - * The document that we are currently using. - * @type {!Document} - */ - get doc() { - return doc; - }, - withDoc: withDoc - }; -})(); diff --git a/chrome/browser/resources/bookmark_manager/js/cr/event.js b/chrome/browser/resources/bookmark_manager/js/cr/event.js deleted file mode 100644 index a02a1f3..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/event.js +++ /dev/null @@ -1,43 +0,0 @@ -// 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 provides a nicer way to create events than what DOM - * provides. These events can be used with DOM EventTarget interfaces as well - * as with {@code cr.EventTarget}. - */ - -cr.define('cr', function() { - - // cr.Event is called CrEvent in here to prevent naming conflicts. We also - // store the original Event in case someone does a global alias of cr.Event. - - const DomEvent = Event; - - /** - * Creates a new event to be used with cr.EventTarget or DOM EventTarget - * objects. - * @param {string} type The name of the event. - * @param {boolean=} opt_bubbles Whether the event bubbles. Default is false. - * @param {boolean=} opt_preventable Whether the default action of the event - * can be prevented. - * @constructor - * @extends {DomEvent} - */ - function CrEvent(type, opt_bubbles, opt_preventable) { - var e = cr.doc.createEvent('Event'); - e.initEvent(type, !!opt_bubbles, !!opt_preventable); - e.__proto__ = CrEvent.prototype; - return e; - } - - CrEvent.prototype = { - __proto__: DomEvent.prototype - }; - - // Export - return { - Event: CrEvent - }; -}); diff --git a/chrome/browser/resources/bookmark_manager/js/cr/eventtarget.js b/chrome/browser/resources/bookmark_manager/js/cr/eventtarget.js deleted file mode 100644 index 5bcb41d..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/eventtarget.js +++ /dev/null @@ -1,104 +0,0 @@ -// 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 contains an implementation of the EventTarget interface - * as defined by DOM Level 2 Events. - */ - -cr.define('cr', function() { - - /** - * Creates a new EventTarget. This class implements the DOM level 2 - * EventTarget interface and can be used wherever those are used. - * @constructor - */ - function EventTarget() { - } - - EventTarget.prototype = { - - /** - * Adds an event listener to the target. - * @param {string} type The name of the event. - * @param {!Function|{handleEvent:Function}} handler The handler for the - * event. This is called when the event is dispatched. - */ - addEventListener: function(type, handler) { - if (!this.listeners_) - this.listeners_ = Object.create(null); - if (!(type in this.listeners_)) { - this.listeners_[type] = [handler]; - } else { - var handlers = this.listeners_[type]; - if (handlers.indexOf(handler) < 0) - handlers.push(handler); - } - }, - - /** - * Removes an event listener from the target. - * @param {string} type The name of the event. - * @param {!Function|{handleEvent:Function}} handler The handler for the - * event. - */ - removeEventListener: function(type, handler) { - if (!this.listeners_) - return; - if (type in this.listeners_) { - var handlers = this.listeners_[type]; - var index = handlers.indexOf(handler); - if (index >= 0) { - // Clean up if this was the last listener. - if (handlers.length == 1) - delete this.listeners_[type]; - else - handlers.splice(index, 1); - } - } - }, - - /** - * Dispatches an event and calls all the listeners that are listening to - * the type of the event. - * @param {!cr.event.Event} event The event to dispatch. - * @return {boolean} Whether the default action was prevented. If someone - * calls preventDefault on the event object then this returns false. - */ - dispatchEvent: function(event) { - if (!this.listeners_) - return true; - - // Since we are using DOM Event objects we need to override some of the - // properties and methods so that we can emulate this correctly. - var self = this; - event.__defineGetter__('target', function() { - return self; - }); - event.preventDefault = function() { - this.returnValue = false; - }; - - var type = event.type; - var prevented = 0; - if (type in this.listeners_) { - // Clone to prevent removal during dispatch - var handlers = this.listeners_[type].concat(); - for (var i = 0, handler; handler = handlers[i]; i++) { - if (handler.handleEvent) - prevented |= handler.handleEvent.call(handler, event) === false; - else - prevented |= handler.call(this, event) === false; - } - } - - return !prevented && event.returnValue; - } - }; - - // Export - return { - EventTarget: EventTarget - }; -}); diff --git a/chrome/browser/resources/bookmark_manager/js/cr/eventtarget_test.html b/chrome/browser/resources/bookmark_manager/js/cr/eventtarget_test.html deleted file mode 100644 index 998e7f1..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/eventtarget_test.html +++ /dev/null @@ -1,139 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<!-- TODO(arv): Check in Closue unit tests and make this run as part of the - tests --> -<script src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"></script> -<script src="../cr.js"></script> -<script src="event.js"></script> -<script src="eventtarget.js"></script> -<script> - -goog.require('goog.testing.jsunit'); - -</script> -</head> -<body> -<script> - -const EventTarget = cr.EventTarget; -const Event = cr.Event; - -function testFunctionListener() { - debugger; - var fi = 0; - function f(e) { - fi++; - } - - var gi = 0; - function g(e) { - gi++; - } - - var et = new EventTarget; - et.addEventListener('f', f); - et.addEventListener('g', g); - - // Adding again should not cause it to be called twice - et.addEventListener('f', f); - et.dispatchEvent(new Event('f')); - assertEquals('Should have been called once', 1, fi); - assertEquals(0, gi); - - et.removeEventListener('f', f); - et.dispatchEvent(new Event('f')); - assertEquals('Should not have been called again', 1, fi); - - et.dispatchEvent(new Event('g')); - assertEquals('Should have been called once', 1, gi); -} - -function testHandleEvent() { - var fi = 0; - var f = { - handleEvent: function(e) { - fi++; - } - }; - - var gi = 0; - var g = { - handleEvent: function(e) { - gi++; - } - }; - - var et = new EventTarget; - et.addEventListener('f', f); - et.addEventListener('g', g); - - // Adding again should not cause it to be called twice - et.addEventListener('f', f); - et.dispatchEvent(new Event('f')); - assertEquals('Should have been called once', 1, fi); - assertEquals(0, gi); - - et.removeEventListener('f', f); - et.dispatchEvent(new Event('f')); - assertEquals('Should not have been called again', 1, fi); - - et.dispatchEvent(new Event('g')); - assertEquals('Should have been called once', 1, gi); -} - -function testPreventDefault() { - var i = 0; - function prevent(e) { - i++; - e.preventDefault(); - } - - var j = 0; - function pass(e) { - j++; - } - - var et = new EventTarget; - et.addEventListener('test', pass); - - assertTrue(et.dispatchEvent(new Event('test'))); - assertEquals(1, j); - - et.addEventListener('test', prevent); - - console.log('NOW'); - assertFalse(et.dispatchEvent(new Event('test'))); - assertEquals(2, j); - assertEquals(1, i); -} - - -function testReturnFalse() { - var i = 0; - function prevent(e) { - i++; - return false; - } - - var j = 0; - function pass(e) { - j++; - } - - var et = new EventTarget; - et.addEventListener('test', pass); - - assertTrue(et.dispatchEvent(new Event('test'))); - assertEquals(1, j); - - et.addEventListener('test', prevent); - - assertFalse(et.dispatchEvent(new Event('test'))); - assertEquals(2, j); - assertEquals(1, i); -} - -</script> -</body> -</html> diff --git a/chrome/browser/resources/bookmark_manager/js/cr/linkcontroller.js b/chrome/browser/resources/bookmark_manager/js/cr/linkcontroller.js deleted file mode 100644 index e6241de..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/linkcontroller.js +++ /dev/null @@ -1,168 +0,0 @@ -// 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') { - if(e.keyIdentifier != 'Enter') - return; - } else if (e.type != 'click' || e.button == 2) { - return; - } - - 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[0], - incognito: incognito - }, function(window) { - urls.forEach(function(url, i) { - if (i > 0) - chrome.tabs.create({ - url: url, - windowId: window.id, - selected: false - }); - }); - }); - } 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 - }; -}); diff --git a/chrome/browser/resources/bookmark_manager/js/cr/linkcontroller_test.html b/chrome/browser/resources/bookmark_manager/js/cr/linkcontroller_test.html deleted file mode 100644 index eb7ebd5..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/linkcontroller_test.html +++ /dev/null @@ -1,353 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<!-- TODO(arv): Check in Closue unit tests and make this run as part of the - tests --> -<script src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"></script> -<script src="../cr.js"></script> -<script src="linkcontroller.js"></script> -<script> - -goog.require('goog.testing.MockControl'); -goog.require('goog.testing.PropertyReplacer'); -goog.require('goog.testing.jsunit'); -goog.require('goog.testing.mockmatchers'); - -</script> -</head> -<body> -<script> - -var mockControl, propertyReplacer, mockWindow; -var chrome = chrome || {}; -chrome.tabs = chrome.tabs || {}; -chrome.windows = chrome.windows || {}; - -var ObjectEqualsMatcher = goog.testing.mockmatchers.ObjectEquals; -var SaveArgumentMatcher = goog.testing.mockmatchers.SaveArgument; - -var MSG = 'MSG'; -var localStrings = { - getStringF: function(msg, number) { - assertEquals('should_open_all', msg); - return MSG + number; - } -}; - -var URL1 = 'http://chromium.org/'; -var URL2 = '#hash'; -var WINDOW_ID = 'WINDOW_ID'; - -function setUp() { - mockControl = new goog.testing.MockControl; - chrome.tabs.create = mockControl.createFunctionMock(); - chrome.windows.create = mockControl.createFunctionMock(); - - propertyReplacer = new goog.testing.PropertyReplacer; - - mockWindow = { - confirm: mockControl.createFunctionMock(), - location: { - get href() { - return 'http://www.google.com/'; - }, - set href(url) { - assertEquals(URL1, url); - } - } - }; -} - -function tearDown() { - mockControl.$tearDown(); - propertyReplacer.reset(); -} - -function testGetWarningMessage() { - var lc = new cr.LinkController(localStrings); - var msg = lc.getWarningMessage(10); - assertEquals(MSG + 10, msg); -} - -function openUrlFromEventHelper(event, isMac, expectedKind) { - var lc = new cr.LinkController(localStrings); - - lc.openUrls = mockControl.createFunctionMock(); - lc.openUrls([URL1], expectedKind); - - propertyReplacer.set(cr, 'isMac', isMac); - - mockControl.$replayAll(); - - lc.openUrlFromEvent(URL1, event); - - mockControl.$verifyAll(); -} - -/////////////////////////////////////////////////////////////////////////////// - -function testOpenUrlFromEventForegroundTab() { - var e = { - type: 'click', - button: 0, - shiftKey: true, - ctrlKey: true - }; - openUrlFromEventHelper(e, false, cr.LinkKind.FOREGROUND_TAB); -} - -function testOpenUrlFromEventForegroundTabMac() { - var e = { - type: 'click', - button: 0, - shiftKey: true, - metaKey: true - }; - openUrlFromEventHelper(e, true, cr.LinkKind.FOREGROUND_TAB); -} - -function testOpenUrlFromEventForegroundTabEnter() { - var e = { - type: 'keydown', - keyIdentifier: 'Enter', - shiftKey: true, - ctrlKey: true - }; - openUrlFromEventHelper(e, false, cr.LinkKind.FOREGROUND_TAB); -} - -function testOpenUrlFromEventForegroundTabEnterMac() { - var e = { - type: 'keydown', - keyIdentifier: 'Enter', - shiftKey: true, - metaKey: true - }; - openUrlFromEventHelper(e, true, cr.LinkKind.FOREGROUND_TAB); -} - -function testOpenUrlFromEventForegroundTabMiddleClick() { - var e = { - type: 'click', - button: 1, - shiftKey: true - }; - openUrlFromEventHelper(e, false, cr.LinkKind.FOREGROUND_TAB); -} - -/////////////////////////////////////////////////////////////////////////////// - -function testOpenUrlFromEventBackgroundTab() { - var e = { - type: 'click', - button: 0, - ctrlKey: true - }; - openUrlFromEventHelper(e, false, cr.LinkKind.BACKGROUND_TAB); -} - -function testOpenUrlFromEventBackgroundTabMac() { - var e = { - type: 'click', - button: 0, - metaKey: true - }; - openUrlFromEventHelper(e, true, cr.LinkKind.BACKGROUND_TAB); -} - -function testOpenUrlFromEventBackgroundTabEnter() { - var e = { - type: 'keydown', - keyIdentifier: 'Enter', - ctrlKey: true - }; - openUrlFromEventHelper(e, false, cr.LinkKind.BACKGROUND_TAB); -} - -function testOpenUrlFromEventBackgroundTabEnterMac() { - var e = { - type: 'keydown', - keyIdentifier: 'Enter', - metaKey: true - }; - openUrlFromEventHelper(e, true, cr.LinkKind.BACKGROUND_TAB); -} - -function testOpenUrlFromEventBackgroundTabMiddleClick() { - var e = { - type: 'click', - button: 1 - }; - openUrlFromEventHelper(e, false, cr.LinkKind.BACKGROUND_TAB); -} - -/////////////////////////////////////////////////////////////////////////////// - -function testOpenUrlFromEventWindow() { - var e = { - type: 'click', - button: 0, - shiftKey: true - }; - openUrlFromEventHelper(e, false, cr.LinkKind.WINDOW); -} - -function testOpenUrlFromEventWindowEnter() { - var e = { - type: 'keydown', - keyIdentifier: 'Enter', - shiftKey: true - }; - openUrlFromEventHelper(e, false, cr.LinkKind.WINDOW); -} - -/////////////////////////////////////////////////////////////////////////////// - -function testOpenUrlFromEventSelf() { - var e = { - type: 'click', - button: 0 - }; - openUrlFromEventHelper(e, false, cr.LinkKind.SELF); -} - -function testOpenUrlFromEventSelfEnter() { - var e = { - type: 'keydown', - keyIdentifier: 'Enter' - }; - openUrlFromEventHelper(e, false, cr.LinkKind.SELF); -} - -/////////////////////////////////////////////////////////////////////////////// - -function testOpenUrl() { - var lc = new cr.LinkController(localStrings); - lc.openUrls = mockControl.createFunctionMock(); - - lc.openUrls(new ObjectEqualsMatcher([URL1]), cr.LinkKind.SELF); - mockControl.$replayAll(); - - lc.openUrl(URL1, cr.LinkKind.SELF); - - mockControl.$verifyAll(); -} - -/////////////////////////////// OpenUrls ////////////////////////////////////// - -function testOpenUrlsTooFew() { - var lc = new cr.LinkController(localStrings); - - mockControl.$replayAll(); - - lc.openUrls([], cr.LinkKind.SELF); - - mockControl.$verifyAll(); -} - - -function testOpenUrlsTooMany() { - var lc = new cr.LinkController(localStrings); - lc.warningLimit = 9; - - var urls = new Array(lc.warningLimit + 1); - lc.window = mockWindow; - - lc.window.confirm('MSG10').$returns(false); - mockControl.$replayAll(); - - lc.openUrls(urls, cr.LinkKind.SELF); - - mockControl.$verifyAll(); -} - -function testOpenUrlsSelf() { - var lc = new cr.LinkController(localStrings); - lc.window = mockWindow; - - mockControl.$replayAll(); - - lc.openUrls([URL1], cr.LinkKind.SELF); - - mockControl.$verifyAll(); -} - -function testOpenUrlsForegroundTab() { - var lc = new cr.LinkController(localStrings); - lc.window = mockWindow; - - chrome.tabs.create(new ObjectEqualsMatcher({url: URL1, selected: true})); - chrome.tabs.create(new ObjectEqualsMatcher({ - url: 'http://www.google.com/#hash', - selected: false - })); - - mockControl.$replayAll(); - - lc.openUrls([URL1, URL2], cr.LinkKind.FOREGROUND_TAB); - - mockControl.$verifyAll(); -} - -function testOpenUrlsBackgroundTab() { - var lc = new cr.LinkController(localStrings); - lc.window = mockWindow; - - chrome.tabs.create(new ObjectEqualsMatcher({url: URL1, selected: false})); - chrome.tabs.create(new ObjectEqualsMatcher({ - url: 'http://www.google.com/#hash', - selected: false - })); - - mockControl.$replayAll(); - - lc.openUrls([URL1, URL2], cr.LinkKind.BACKGROUND_TAB); - - mockControl.$verifyAll(); -} - -function testOpenUrlsWindow() { - var lc = new cr.LinkController(localStrings); - lc.window = mockWindow; - - var callbackMatcher = new SaveArgumentMatcher; - chrome.windows.create(new ObjectEqualsMatcher({url: URL1, incognito: false}), - callbackMatcher); - chrome.tabs.create(new ObjectEqualsMatcher({ - url: 'http://www.google.com/#hash', - windowId: WINDOW_ID, - selected: false - })); - - mockControl.$replayAll(); - - lc.openUrls([URL1, URL2], cr.LinkKind.WINDOW); - callbackMatcher.arg({id: WINDOW_ID}); - - mockControl.$verifyAll(); -} - -function testOpenUrlsIncognito() { - var lc = new cr.LinkController(localStrings); - lc.window = mockWindow; - - var callbackMatcher = new SaveArgumentMatcher; - chrome.windows.create(new ObjectEqualsMatcher({url: URL1, incognito: true}), - callbackMatcher); - chrome.tabs.create(new ObjectEqualsMatcher({ - url: 'http://www.google.com/#hash', - windowId: WINDOW_ID, - selected: false - })); - - mockControl.$replayAll(); - - lc.openUrls([URL1, URL2], cr.LinkKind.INCOGNITO); - callbackMatcher.arg({id: WINDOW_ID}); - - mockControl.$verifyAll(); -} - -</script> -</body> -</html> diff --git a/chrome/browser/resources/bookmark_manager/js/cr/promise.js b/chrome/browser/resources/bookmark_manager/js/cr/promise.js deleted file mode 100644 index a9d233a..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/promise.js +++ /dev/null @@ -1,213 +0,0 @@ -// 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 implementes a future promise class. - */ - -cr.define('cr', function() { - - /** - * Sentinel used to mark a value as pending. - */ - const PENDING_VALUE = {}; - - /** - * Creates a future promise. - * @param {*=} opt_value The value to set the promise to. If set completes - * the promise immediately. - * @constructor - */ - function Promise(opt_value) { - /** - * An array of the callbacks. - * @type {!Array.<!Function>} - * @private - */ - this.callbacks_ = []; - - if (arguments.length > 0) - this.value = opt_value; - } - - Promise.prototype = { - /** - * The current value. - * @type {*} - * @private - */ - value_: PENDING_VALUE, - - /** - * The value of the future promise. Accessing this before the promise has - * been fulfilled will throw an error. If this is set to an exception - * accessing this will throw as well. - * @type {*} - */ - get value() { - return this.done ? this.value_ : undefined; - }, - set value(value) { - if (!this.done) { - this.value_ = value; - for (var i = 0; i < this.callbacks_.length; i++) { - this.callbacks_[i].call(null, value); - } - this.callbacks_.length = 0; - } - }, - - /** - * Whether the future promise has been fulfilled. - * @type {boolean} - */ - get done() { - return this.value_ !== PENDING_VALUE; - }, - - /** - * Adds a listener to the future promise. The function will be called when - * the promise is fulfilled. If the promise is already fullfilled this will - * never call the function. - * @param {!Function} fun The function to call. - */ - addListener: function(fun) { - if (this.done) - fun(this.value); - else - this.callbacks_.push(fun); - }, - - /** - * Removes a previously added listener from the future promise. - * @param {!Function} fun The function to remove. - */ - removeListener: function(fun) { - var i = this.callbacks_.indexOf(fun); - if (i >= 0) - this.callbacks_.splice(i, 1); - }, - - /** - * If the promise is done then this returns the string representation of - * the value. - * @return {string} The string representation of the promise. - * @override - */ - toString: function() { - if (this.done) - return String(this.value); - else - return '[object Promise]'; - }, - - /** - * Override to allow arithmetic. - * @override - */ - valueOf: function() { - return this.value; - } - }; - - /** - * When a future promise is done call {@code fun}. This also calls the - * function if the promise has already been fulfilled. - * @param {!Promise} p The promise. - * @param {!Function} fun The function to call when the promise is fulfilled. - */ - Promise.when = function(p, fun) { - p.addListener(fun); - }; - - /** - * Creates a new promise the will be fulfilled after {@code t} ms. - * @param {number} t The time to wait before the promise is fulfilled. - * @param {*=} opt_value The value to return after the wait. - * @return {!Promise} The new future promise. - */ - Promise.wait = function(t, opt_value) { - var p = new Promise; - window.setTimeout(function() { - p.value = opt_value; - }, t); - return p; - }; - - /** - * Creates a new future promise that is fulfilled when any of the promises are - * fulfilled. The value of the returned promise will be the value of the first - * fulfilled promise. - * @param {...!Promise} var_args The promises used to build up the new - * promise. - * @return {!Promise} The new promise that will be fulfilled when any of the - * passed in promises are fulfilled. - */ - Promise.any = function(var_args) { - var p = new Promise; - function f(v) { - p.value = v; - } - for (var i = 0; i < arguments.length; i++) { - arguments[i].addListener(f); - } - return p; - }; - - /** - * Creates a new future promise that is fulfilled when all of the promises are - * fulfilled. The value of the returned promise is an array of the values of - * the promises passed in. - * @param {...!Promise} var_args The promises used to build up the new - * promise. - * @return {!Promise} The promise that wraps all the promises in the array. - */ - Promise.all = function(var_args) { - var p = new Promise; - var args = Array.prototype.slice.call(arguments); - var count = args.length; - if (!count) { - p.value = []; - return p; - } - - function f(v) { - count--; - if (!count) { - p.value = args.map(function(argP) { - return argP.value; - }); - } - } - - // Do not use count here since count may be decremented in the call to - // addListener if the promise is already done. - for (var i = 0; i < args.length; i++) { - args[i].addListener(f); - } - - return p; - }; - - /** - * Wraps an event in a future promise. - * @param {!EventTarget} target The object that dispatches the event. - * @param {string} type The type of the event. - * @param {boolean=} opt_useCapture Whether to listen to the capture phase or - * the bubble phase. - * @return {!Promise} The promise that will be fulfilled when the event is - * dispatched. - */ - Promise.event = function(target, type, opt_useCapture) { - var p = new Promise; - target.addEventListener(type, function(e) { - p.value = e; - }, opt_useCapture); - return p; - }; - - return { - Promise: Promise - }; -}); diff --git a/chrome/browser/resources/bookmark_manager/js/cr/promise_test.html b/chrome/browser/resources/bookmark_manager/js/cr/promise_test.html deleted file mode 100644 index 5c9ae1d..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/promise_test.html +++ /dev/null @@ -1,251 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<!-- TODO(arv): Check in Closue unit tests and make this run as part of the - tests --> -<script src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"></script> -<script src="../cr.js"></script> -<script src="promise.js"></script> -<script src="event.js"></script> -<script> - -goog.require('goog.testing.jsunit'); -goog.require('goog.testing.MockClock'); - -</script> -</head> -<body> -<script> - -var mockClock; - -function setUp() { - mockClock = new goog.testing.MockClock(); - mockClock.install(); -} - -function tearDown() { - mockClock.uninstall(); -} - -const Promise = cr.Promise; - -function testCallbacks() { - var calls1 = 0; - var calls2 = 0; - var V = {}; - function f1(v) { - calls1++; - assertEquals(V, v); - } - function f2(v) { - calls2++; - assertEquals(V, v); - } - var p = new Promise; - p.addListener(f1); - p.addListener(f2); - p.value = V; - assertEquals(1, calls1); - assertEquals(1, calls2); -} - -function testCallbacks2() { - var calls1 = 0; - var calls2 = 0; - var V = {}; - function f1(v) { - calls1++; - assertEquals(V, v); - } - function f2(v) { - calls2++; - assertEquals(V, v); - } - var p = new Promise; - p.addListener(f1); - p.addListener(f2); - p.removeListener(f1); - p.value = V; - assertEquals(0, calls1); - assertEquals(1, calls2); -} - -function testCallbacks3() { - var calls1 = 0; - var calls2 = 0; - var V = {}; - function f1(v) { - calls1++; - assertEquals(V, v); - } - function f2(v) { - calls2++; - assertEquals(V, v); - } - var p = new Promise; - p.addListener(f1); - assertEquals(0, calls1); - assertEquals(0, calls2); - p.value = V; - assertEquals(1, calls1); - assertEquals(0, calls2); - p.addListener(f2); - assertEquals(1, calls1); - assertEquals(1, calls2); -} - -function testCallbacks4() { - var calls1 = 0; - var calls2 = 0; - var V = {}; - function f1(v) { - calls1++; - assertEquals(V, v); - } - function f2(v) { - calls2++; - assertEquals(V, v); - } - var p = new Promise(V); - p.addListener(f1); - p.addListener(f2); - assertEquals(1, calls1); - assertEquals(1, calls2); -} - -function testThisInCallback() { - var calls = 0; - var V = {}; - function f(v) { - calls++; - assertEquals(V, v); - assertNotEquals(p, this); - } - var p = new Promise; - p.addListener(f); - p.value = V; - assertEquals(1, calls); -} - -function testPending() { - var p = new Promise; - assertEquals(undefined, p.value); - assertFalse(p.done); -} - -function testValueCanBeUndefined() { - var p = new Promise; - p.value = undefined; - assertEquals(undefined, p.value); - assertTrue(p.done); -} - -function testDone() { - var p = new Promise; - assertFalse(p.done); - p.value = 42; - assertTrue(p.done); -} - -function testWhen() { - const V = {}; - var calls = 0; - var p = new Promise; - p.value = V; - Promise.when(p, function(v) { - assertEquals(V, v); - calls++; - }); - assertEquals(1, calls); -} - -function testWhen2() { - const V = {}; - var calls = 0; - var p = new Promise; - Promise.when(p, function(v) { - assertEquals(V, v); - calls++; - }); - p.value = V; - assertEquals(1, calls); -} - -function testWait() { - const S = {}; - var p = Promise.wait(1000, S); - assertFalse(p.done); - mockClock.tick(500); - assertFalse(p.done); - mockClock.tick(500); - assertTrue(p.done); - assertEquals(S, p.value); -} - -function testAny() { - var p1 = new Promise; - var p2 = new Promise; - var p3 = new Promise; - - var any = Promise.any(p1, p2, p3); - p2.value = 2; - assertEquals(2, any.value); - p1.value = 1; - assertEquals(2, any.value); -} - -function testAll() { - var p1 = new Promise; - var p2 = new Promise; - var p3 = new Promise; - - var pAll = Promise.all(p1, p2, p3); - p1.value = 1; - p2.value = 2; - p3.value = 3; - assertArrayEquals([1, 2, 3], pAll.value); -} - -function testAllEmpty() { - var pAll = Promise.all(); - assertArrayEquals([], pAll.value); -} - -function testAllAlreadyDone() { - var p1 = new Promise(1); - var p2 = new Promise(2); - var p3 = new Promise(3); - - var pAll = Promise.all(p1, p2, p3); - assertArrayEquals([1, 2, 3], pAll.value); -} - -function testEvent() { - var p = Promise.event(document.body, 'foo'); - var e = new cr.Event('foo'); - document.body.dispatchEvent(e); - assertEquals(e, p.value); -} - -function testToString() { - var p1 = new Promise; - assertEquals('[object Promise]', String(p1)); - - var p2 = new Promise; - p2.value = 'Hello world'; - assertEquals('Hello world', String(p2)); -} - -function testValueOf() { - var p = new Promise; - p.value = 42; - - assertTrue(p < 43); - assertTrue(p > 41); - assertTrue(p == 42); -} - -</script> -</body> -</html> diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui.js b/chrome/browser/resources/bookmark_manager/js/cr/ui.js deleted file mode 100644 index d87c04a..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/ui.js +++ /dev/null @@ -1,173 +0,0 @@ -// 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. - -cr.define('cr.ui', function() { - - /** - * Decorates elements as an instance of a class. - * @param {string|!Element} source The way to find the element(s) to decorate. - * If this is a string then {@code querySeletorAll} is used to find the - * elements to decorate. - * @param {!Function} constr The constructor to decorate with. The constr - * needs to have a {@code decorate} function. - */ - function decorate(source, constr) { - var elements; - if (typeof source == 'string') - elements = cr.doc.querySelectorAll(source); - else - elements = [source]; - - for (var i = 0, el; el = elements[i]; i++) { - if (!(el instanceof constr)) - constr.decorate(el); - } - } - - /** - * Helper function for creating new element for define. - */ - function createElementHelper(tagName, opt_bag) { - // Allow passing in ownerDocument to create in a different document. - var doc; - if (opt_bag && opt_bag.ownerDocument) - doc = opt_bag.ownerDocument; - else - doc = cr.doc; - return doc.createElement(tagName); - } - - /** - * Creates the constructor for a UI element class. - * - * Usage: - * <pre> - * var List = cr.ui.define('list'); - * List.prototype = { - * __proto__: HTMLUListElement.prototype, - * decorate: function() { - * ... - * }, - * ... - * }; - * </pre> - * - * @param {string|Function} tagNameOrFunction The tagName or - * function to use for newly created elements. If this is a function it - * needs to return a new element when called. - * @return {function(Object=):Element} The constructor function which takes - * an optional property bag. The function also has a static - * {@code decorate} method added to it. - */ - function define(tagNameOrFunction) { - var createFunction, tagName; - if (typeof tagNameOrFunction == 'function') { - createFunction = tagNameOrFunction; - tagName = ''; - } else { - createFunction = createElementHelper; - tagName = tagNameOrFunction; - } - - /** - * Creates a new UI element constructor. - * @param {Object=} opt_propertyBag Optional bag of properties to set on the - * object after created. The property {@code ownerDocument} is special - * cased and it allows you to create the element in a different - * document than the default. - * @constructor - */ - function f(opt_propertyBag) { - var el = createFunction(tagName, opt_propertyBag); - f.decorate(el); - for (var propertyName in opt_propertyBag) { - el[propertyName] = opt_propertyBag[propertyName]; - } - return el; - } - - /** - * Decorates an element as a UI element class. - * @param {!Element} el The element to decorate. - */ - f.decorate = function(el) { - el.__proto__ = f.prototype; - el.decorate(); - }; - - return f; - } - - /** - * Input elements do not grow and shrink with their content. This is a simple - * (and not very efficient) way of handling shrinking to content with support - * for min width and limited by the width of the parent element. - * @param {HTMLElement} el The element to limit the width for. - * @param {number} parentEl The parent element that should limit the size. - * @param {number} min The minimum width. - */ - function limitInputWidth(el, parentEl, min) { - // Needs a size larger than borders - el.style.width = '10px'; - var doc = el.ownerDocument; - var win = doc.defaultView; - var computedStyle = win.getComputedStyle(el); - var parentComputedStyle = win.getComputedStyle(parentEl); - var rtl = computedStyle.direction == 'rtl'; - - // To get the max width we get the width of the treeItem minus the position - // of the input. - var inputRect = el.getBoundingClientRect(); // box-sizing - var parentRect = parentEl.getBoundingClientRect(); - var startPos = rtl ? parentRect.right - inputRect.right : - inputRect.left - parentRect.left; - - // Add up border and padding of the input. - var inner = parseInt(computedStyle.borderLeftWidth, 10) + - parseInt(computedStyle.paddingLeft, 10) + - parseInt(computedStyle.paddingRight, 10) + - parseInt(computedStyle.borderRightWidth, 10); - - // We also need to subtract the padding of parent to prevent it to overflow. - var parentPadding = rtl ? parseInt(parentComputedStyle.paddingLeft, 10) : - parseInt(parentComputedStyle.paddingRight, 10); - - // The magic number 14 comes from trial and error :'( It consists of: - // border + padding + treeItem.paddingEnd + treeItem.borderEnd + - // tree.paddingEnd - var max = parentEl.clientWidth - startPos - inner - parentPadding; - - var pcs = getComputedStyle(parentEl); - console.log('pcs', 'borderLeft', pcs.borderLeftWidth, - 'paddingLeft', pcs.paddingLeft, - 'paddingRight', pcs.paddingRight, - 'borderRight', pcs.borderRightWidth, - 'width', pcs.width, - 'clientWidth', parentEl.clientWidth, - 'offsetWidth', parentEl.offsetWidth); - - function limit() { - if (el.scrollWidth > max) { - el.style.width = max + 'px'; - } else { - el.style.width = 0; - var sw = el.scrollWidth; - if (sw < min) { - el.style.width = min + 'px'; - } else { - el.style.width = sw + 'px'; - } - } - } - - el.addEventListener('input', limit); - limit(); - } - - return { - decorate: decorate, - define: define, - limitInputWidth: limitInputWidth - }; -}); diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/command.js b/chrome/browser/resources/bookmark_manager/js/cr/ui/command.js deleted file mode 100644 index 4df2275..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/ui/command.js +++ /dev/null @@ -1,295 +0,0 @@ -// 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 A command is an abstraction of an action a user can do in the - * UI. - * - * When the focus changes in the document for each command a canExecute event - * is dispatched on the active element. By listening to this event you can - * enable and disable the command by setting the event.canExecute property. - * - * When a command is executed a command event is dispatched on the active - * element. Note that you should stop the propagation after you have handled the - * command if there might be other command listeners higher up in the DOM tree. - */ - -cr.define('cr.ui', function() { - - /** - * This is used to identify keyboard shortcuts. - * @param {string} shortcut The text used to describe the keys for this - * keyboard shortcut. - * @constructor - */ - function KeyboardShortcut(shortcut) { - var mods = {}; - var ident = ''; - shortcut.split('-').forEach(function(part) { - var partLc = part.toLowerCase(); - switch (partLc) { - case 'alt': - case 'ctrl': - case 'meta': - case 'shift': - mods[partLc + 'Key'] = true; - break; - default: - if (ident) - throw Error('Invalid shortcut'); - ident = part; - } - }); - - this.ident_ = ident; - this.mods_ = mods; - } - - KeyboardShortcut.prototype = { - /** - * Wether the keyboard shortcut object mathes a keyboard event. - * @param {!Event} e The keyboard event object. - * @return {boolean} Whether we found a match or not. - */ - matchesEvent: function(e) { - if (e.keyIdentifier == this.ident_) { - // All keyboard modifiers needs to match. - var mods = this.mods_; - return ['altKey', 'ctrlKey', 'metaKey', 'shiftKey'].every(function(k) { - return e[k] == !!mods[k]; - }); - } - return false; - } - }; - - /** - * Creates a new command element. - * @constructor - * @extends {HTMLElement} - */ - var Command = cr.ui.define('command'); - - Command.prototype = { - __proto__: HTMLElement.prototype, - - /** - * Initializes the command. - */ - decorate: function() { - CommandManager.init(this.ownerDocument); - }, - - /** - * Executes the command. This dispatches a command event on the active - * element. If the command is {@code disabled} this does nothing. - */ - execute: function() { - if (this.disabled) - return; - var doc = this.ownerDocument; - if (doc.activeElement) { - var e = new cr.Event('command', true, false); - e.command = this; - doc.activeElement.dispatchEvent(e); - } - }, - - /** - * Call this when there have been changes that might change whether the - * command can be executed or not. - */ - canExecuteChange: function() { - dispatchCanExecuteEvent(this, this.ownerDocument.activeElement); - }, - - /** - * The keyboard shortcut that triggers the command. This is a string - * consisting of a keyIdentifier (as reported by WebKit in keydown) as - * well as optional key modifiers joinded with a '-'. - * - * Multiple keyboard shortcuts can be provided by separating them by - * whitespace. - * - * For example: - * "F1" - * "U+0008-Meta" for Apple command backspace. - * "U+0041-Ctrl" for Control A - * "U+007F U+0008-Meta" for Delete and Command Backspace - * - * @type {string} - */ - shortcut_: '', - get shortcut() { - return this.shortcut_; - }, - set shortcut(shortcut) { - var oldShortcut = this.shortcut_; - if (shortcut !== oldShortcut) { - this.keyboardShortcuts_ = shortcut.split(/\s+/).map(function(shortcut) { - return new KeyboardShortcut(shortcut); - }); - - // Set this after the keyboardShortcuts_ since that might throw. - this.shortcut_ = shortcut; - cr.dispatchPropertyChange(this, 'shortcut', this.shortcut_, - oldShortcut); - } - }, - - /** - * Whether the event object matches the shortcut for this command. - * @param {!Event} e The key event object. - * @return {boolean} Whether it matched or not. - */ - matchesEvent: function(e) { - if (!this.keyboardShortcuts_) - return false; - - return this.keyboardShortcuts_.some(function(keyboardShortcut) { - return keyboardShortcut.matchesEvent(e); - }); - } - }; - - /** - * The label of the command. - * @type {string} - */ - cr.defineProperty(Command, 'label', cr.PropertyKind.ATTR); - - /** - * Whether the command is disabled or not. - * @type {boolean} - */ - cr.defineProperty(Command, 'disabled', cr.PropertyKind.BOOL_ATTR); - - /** - * Whether the command is hidden or not. - * @type {boolean} - */ - cr.defineProperty(Command, 'hidden', cr.PropertyKind.BOOL_ATTR); - - /** - * Dispatches a canExecute event on the target. - * @param {cr.ui.Command} command The command that we are testing for. - * @param {Element} target The target element to dispatch the event on. - */ - function dispatchCanExecuteEvent(command, target) { - var e = new CanExecuteEvent(command, true) - target.dispatchEvent(e); - command.disabled = !e.canExecute; - } - - /** - * The command managers for different documents. - */ - var commandManagers = {}; - - /** - * Keeps track of the focused element and updates the commands when the focus - * changes. - * @param {!Document} doc The document that we are managing the commands for. - * @constructor - */ - function CommandManager(doc) { - doc.addEventListener('focus', cr.bind(this.handleFocus_, this), true); - // Make sure we add the listener to the bubbling phase so that elements can - // prevent the command. - doc.addEventListener('keydown', cr.bind(this.handleKeyDown_, this), false); - } - - /** - * Initializes a command manager for the document as needed. - * @param {!Document} doc The document to manage the commands for. - */ - CommandManager.init = function(doc) { - var uid = cr.getUid(doc); - if (!(uid in commandManagers)) { - commandManagers[uid] = new CommandManager(doc); - } - }, - - CommandManager.prototype = { - - /** - * Handles focus changes on the document. - * @param {Event} e The focus event object. - * @private - */ - handleFocus_: function(e) { - var target = e.target; - var commands = Array.prototype.slice.call( - target.ownerDocument.querySelectorAll('command')); - - commands.forEach(function(command) { - dispatchCanExecuteEvent(command, target); - }); - }, - - /** - * Handles the keydown event and routes it to the right command. - * @param {!Event} e The keydown event. - */ - handleKeyDown_: function(e) { - var target = e.target; - var commands = Array.prototype.slice.call( - target.ownerDocument.querySelectorAll('command')); - - for (var i = 0, command; command = commands[i]; i++) { - if (!command.disabled && command.matchesEvent(e)) { - e.preventDefault(); - // We do not want any other element to handle this. - e.stopPropagation(); - - command.execute(); - return; - } - } - } - }; - - /** - * The event type used for canExecute events. - * @param {!cr.ui.Command} command The command that we are evaluating. - * @extends {Event} - */ - function CanExecuteEvent(command) { - var e = command.ownerDocument.createEvent('Event'); - e.initEvent('canExecute', true, false); - e.__proto__ = CanExecuteEvent.prototype; - e.command = command; - return e; - } - - CanExecuteEvent.prototype = { - __proto__: Event.prototype, - - /** - * The current command - * @type {cr.ui.Command} - */ - command: null, - - /** - * Whether the target can execute the command. Setting this also stops the - * propagation. - * @type {boolean} - */ - canExecute_: false, - get canExecute() { - return this.canExecute_; - }, - set canExecute(canExecute) { - this.canExecute_ = canExecute; - this.stopPropagation(); - } - }; - - // Export - return { - Command: Command, - CanExecuteEvent: CanExecuteEvent - }; -}); diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/contextmenuhandler.js b/chrome/browser/resources/bookmark_manager/js/cr/ui/contextmenuhandler.js deleted file mode 100644 index 2d96a4c..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/ui/contextmenuhandler.js +++ /dev/null @@ -1,225 +0,0 @@ -// 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. - -cr.define('cr.ui', function() { - - /** - * Handles context menus. - * @constructor - */ - function ContextMenuHandler() {} - - ContextMenuHandler.prototype = { - - /** - * The menu that we are currently showing. - * @type {cr.ui.Menu} - */ - menu_: null, - get menu() { - return this.menu_; - }, - - /** - * Shows a menu as a context menu. - * @param {!Event} e The event triggering the show (usally a contextmenu - * event). - * @param {!cr.ui.Menu} menu The menu to show. - */ - showMenu: function(e, menu) { - this.menu_ = menu; - - menu.style.display = 'block'; - // when the menu is shown we steal all keyboard events. - menu.ownerDocument.addEventListener('keydown', this, true); - menu.ownerDocument.addEventListener('mousedown', this, true); - menu.ownerDocument.addEventListener('blur', this, true); - menu.addEventListener('activate', this); - this.positionMenu_(e, menu); - }, - - /** - * Hide the currently shown menu. - */ - hideMenu: function() { - var menu = this.menu; - if (!menu) - return; - - menu.style.display = 'none'; - menu.ownerDocument.removeEventListener('keydown', this, true); - menu.ownerDocument.removeEventListener('mousedown', this, true); - menu.ownerDocument.removeEventListener('blur', this, true); - menu.removeEventListener('activate', this); - menu.selectedIndex = -1; - this.menu_ = null; - - // On windows we might hide the menu in a right mouse button up and if - // that is the case we wait some short period before we allow the menu - // to be shown again. - this.hideTimestamp_ = Date.now(); - }, - - /** - * Positions the menu - * @param {!Event} e The event object triggering the showing. - * @param {!cr.ui.Menu} menu The menu to position. - * @private - */ - positionMenu_: function(e, menu) { - // TODO(arv): Handle scrolled documents when needed. - - var element = e.currentTarget; - var x, y; - // When the user presses the context menu key (on the keyboard) we need - // to detect this. - if (e.screenX == 0 && e.screenY == 0) { - var rect = element.getRectForContextMenu ? - element.getRectForContextMenu() : - element.getBoundingClientRect(); - var offset = Math.min(rect.width, rect.height) / 2; - x = rect.left + offset; - y = rect.top + offset; - } else { - x = e.clientX; - y = e.clientY; - } - - var menuRect = menu.getBoundingClientRect(); - var bodyRect = menu.ownerDocument.body.getBoundingClientRect(); - - // Does menu fit below? - if (y + menuRect.height > bodyRect.height) { - // Does menu fit above? - if (y - menuRect.height >= 0) { - y -= menuRect.height; - } else { - // Menu did not fit above nor below. - y = 0; - // We could resize the menu here but lets not worry about that at this - // point. - } - } - - // Does menu fit to the right? - if (x + menuRect.width > bodyRect.width) { - // Does menu fit to the left? - if (x - menuRect.width >= 0) { - x -= menuRect.width; - } else { - // Menu did not fit to the right nor to the left. - x = 0; - // We could resize the menu here but lets not worry about that at this - // point. - } - } - - menu.style.left = x + 'px'; - menu.style.top = y + 'px'; - }, - - /** - * Handles event callbacks. - * @param {!Event} e The event object. - */ - handleEvent: function(e) { - // Context menu is handled even when we have no menu. - if (e.type != 'contextmenu' && !this.menu) - return; - - switch (e.type) { - case 'mousedown': - if (!this.menu.contains(e.target)) - this.hideMenu(); - else - e.preventDefault(); - break; - case 'keydown': - // keyIdentifier does not report 'Esc' correctly - if (e.keyCode == 27 /* Esc */) { - this.hideMenu(); - - // If the menu is visible we let it handle all the keyboard events. - } else if (this.menu) { - this.menu.handleKeyDown(e); - e.preventDefault(); - e.stopPropagation(); - } - break; - - case 'activate': - case 'blur': - this.hideMenu(); - break; - - case 'contextmenu': - if ((!this.menu || !this.menu.contains(e.target)) && - (!this.hideTimestamp_ || Date.now() - this.hideTimestamp_ > 50)) - this.showMenu(e, e.currentTarget.contextMenu); - e.preventDefault(); - // Don't allow elements further up in the DOM to show their menus. - e.stopPropagation(); - break; - } - }, - - /** - * Adds a contextMenu property to an element or element class. - * @param {!Element|!Function} element The element or class to add the - * contextMenu property to. - */ - addContextMenuProperty: function(element) { - if (typeof element == 'function') - element = element.prototype; - - element.__defineGetter__('contextMenu', function() { - return this.contextMenu_; - }); - element.__defineSetter__('contextMenu', function(menu) { - var oldContextMenu = this.contextMenu; - - if (typeof menu == 'string' && menu[0] == '#') { - menu = this.ownerDocument.getElementById(menu.slice(1)); - cr.ui.decorate(menu, Menu); - } - - if (menu === oldContextMenu) - return; - - if (oldContextMenu && !menu) - this.removeEventListener('contextmenu', contextMenuHandler); - if (menu && !oldContextMenu) - this.addEventListener('contextmenu', contextMenuHandler); - - this.contextMenu_ = menu; - - if (menu && menu.id) - this.setAttribute('contextmenu', '#' + menu.id); - - cr.dispatchPropertyChange(this, 'contextMenu', menu, oldContextMenu); - }); - - if (!element.getRectForContextMenu) { - /** - * @return {!ClientRect} The rect to use for positioning the context - * menu when the context menu is not opened using a mouse position. - */ - element.getRectForContextMenu = function() { - return this.getBoundingClientRect(); - }; - } - } - }; - - /** - * The singleton context menu handler. - * @type {!ContextMenuHandler} - */ - var contextMenuHandler = new ContextMenuHandler; - - // Export - return { - contextMenuHandler: contextMenuHandler - }; -}); diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/list.js b/chrome/browser/resources/bookmark_manager/js/cr/ui/list.js deleted file mode 100644 index f221279..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/ui/list.js +++ /dev/null @@ -1,265 +0,0 @@ -// 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. - -// require: listselectionmodel.js - -/** - * @fileoverview This implements a list control. - */ - -cr.define('cr.ui', function() { - const ListSelectionModel = cr.ui.ListSelectionModel; - - /** - * Whether a mouse event is inside the element viewport. This will return - * false if the mouseevent was generated over a border or a scrollbar. - * @param {!HTMLElement} el The element to test the event with. - * @param {!Event} e The mouse event. - * @param {boolean} Whether the mouse event was inside the viewport. - */ - function inViewport(el, e) { - var rect = el.getBoundingClientRect(); - var x = e.clientX; - var y = e.clientY; - return x >= rect.left + el.clientLeft && - x < rect.left + el.clientLeft + el.clientWidth && - y >= rect.top + el.clientTop && - y < rect.top + el.clientTop + el.clientHeight; - } - - /** - * Creates a new list element. - * @param {Object=} opt_propertyBag Optional properties. - * @constructor - * @extends {HTMLUListElement} - */ - var List = cr.ui.define('list'); - - List.prototype = { - __proto__: HTMLUListElement.prototype, - - /** - * The selection model to use. - * @type {cr.ui.ListSelectionModel} - */ - get selectionModel() { - return this.selectionModel_; - }, - set selectionModel(sm) { - var oldSm = this.selectionModel_; - if (oldSm == sm) - return; - - if (!this.boundHandleOnChange_) { - this.boundHandleOnChange_ = cr.bind(this.handleOnChange_, this); - this.boundHandleLeadChange_ = cr.bind(this.handleLeadChange_, this); - } - - if (oldSm) { - oldSm.removeEventListener('change', this.boundHandleOnChange_); - oldSm.removeEventListener('leadItemChange', this.boundHandleLeadChange_); - } - - this.selectionModel_ = sm; - - if (sm) { - sm.addEventListener('change', this.boundHandleOnChange_); - sm.addEventListener('leadItemChange', this.boundHandleLeadChange_); - } - }, - - /** - * Convenience alias for selectionModel.selectedItem - * @type {cr.ui.ListItem} - */ - get selectedItem() { - return this.selectionModel.selectedItem; - }, - set selectedItem(selectedItem) { - this.selectionModel.selectedItem = selectedItem; - }, - - /** - * Convenience alias for selectionModel.selectedItems - * @type {!Array<cr.ui.ListItem>} - */ - get selectedItems() { - return this.selectionModel.selectedItems; - }, - - /** - * The HTML elements representing the items. This is just all the element - * children but subclasses may override this to filter out certain elements. - * @type {HTMLCollection} - */ - get items() { - return this.children; - }, - - batchCount_: 0, - - /** - * When adding a large collection of items to the list, the code should be - * wrapped in the startBatchAdd and startBatchEnd to increase performance. - * This hides the list while it is being built, and prevents it from - * incurring measurement performance hits in between each item. - * Be sure that the code will not return without calling finishBatchAdd - * or the list will not be shown. - * @private - */ - startBatchAdd: function() { - // If we're already in a batch, don't overwrite original display style. - if (this.batchCount_ == 0) { - this.originalDisplayStyle_ = this.style.display; - this.style.display = 'none'; - } - this.batchCount_++; - }, - - /** - * See startBatchAdd. - * @private - */ - finishBatchAdd: function() { - this.batchCount_--; - if (this.batchCount_ == 0) { - this.style.display = this.originalDisplayStyle_; - delete this.originalDisplayStyle; - } - }, - - add: function(listItem) { - this.appendChild(listItem); - - var uid = cr.getUid(listItem); - this.uidToListItem_[uid] = listItem; - - this.selectionModel.add(listItem); - }, - - addAt: function(listItem, index) { - this.insertBefore(listItem, this.items[index]); - - var uid = cr.getUid(listItem); - this.uidToListItem_[uid] = listItem; - - this.selectionModel.add(listItem); - }, - - remove: function(listItem) { - this.selectionModel.remove(listItem); - - this.removeChild(listItem); - - var uid = cr.getUid(listItem); - delete this.uidToListItem_[uid]; - }, - - clear: function() { - this.innerHTML = ''; - this.selectionModel.clear(); - }, - - /** - * Initializes the element. - */ - decorate: function() { - this.uidToListItem_ = {}; - - this.selectionModel = new ListSelectionModel(this); - - this.addEventListener('mousedown', this.handleMouseDownUp_); - this.addEventListener('mouseup', this.handleMouseDownUp_); - this.addEventListener('keydown', this.handleKeyDown); - - // Make list focusable - if (!this.hasAttribute('tabindex')) - this.tabIndex = 0; - }, - - /** - * Callback for mousedown and mouseup events. - * @param {Event} e The mouse event object. - * @private - */ - handleMouseDownUp_: function(e) { - var target = e.target; - - // If the target was this element we need to make sure that the user did - // not click on a border or a scrollbar. - if (target == this && !inViewport(target, e)) - return; - - while (target && target.parentNode != this) { - target = target.parentNode; - } - - this.selectionModel.handleMouseDownUp(e, target); - }, - - /** - * Handle a keydown event. - * @param {Event} e The keydown event. - * @return {boolean} Whether the key event was handled. - */ - handleKeyDown: function(e) { - return this.selectionModel.handleKeyDown(e); - }, - - /** - * Callback from the selection model. We dispatch {@code change} events - * when the selection changes. - * @param {!cr.Event} e Event with change info. - * @private - */ - handleOnChange_: function(ce) { - ce.changes.forEach(function(change) { - var listItem = this.uidToListItem_[change.uid]; - listItem.selected = change.selected; - }, this); - - cr.dispatchSimpleEvent(this, 'change'); - }, - - /** - * Handles a change of the lead item from the selection model. - * @property {Event} pe The property change event. - * @private - */ - handleLeadChange_: function(pe) { - if (pe.oldValue) { - pe.oldValue.lead = false; - } - if (pe.newValue) { - pe.newValue.lead = true; - } - }, - - /** - * Gets a unique ID for an item. This needs to be unique to the list but - * does not have to be gloabally unique. This uses {@code cr.getUid} by - * default. Override to provide a more efficient way to get the unique ID. - * @param {cr.ui.ListItem} item The item to get the unique ID for. - * @return - */ - itemToUid: function(item) { - return cr.getUid(item); - }, - - /** - * @return {!ClientRect} The rect to use for the context menu. - */ - getRectForContextMenu: function() { - // TODO(arv): Add trait support so we can share more code between trees - // and lists. - if (this.selectedItem) - return this.selectedItem.getBoundingClientRect(); - return this.getBoundingClientRect(); - } - }; - - return { - List: List - } -}); diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/listitem.js b/chrome/browser/resources/bookmark_manager/js/cr/ui/listitem.js deleted file mode 100644 index 0cd8826..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/ui/listitem.js +++ /dev/null @@ -1,58 +0,0 @@ -// 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. - -cr.define('cr.ui', function() { - - /** - * Creates a new list item element. - * @param {string} opt_label The text label for the item. - * @constructor - * @extends {HTMLLIElement} - */ - var ListItem = cr.ui.define('li'); - - ListItem.prototype = { - __proto__: HTMLLIElement.prototype, - - /** - * Plain text label. - * @type {string} - */ - get label() { - return this.textContent; - }, - set label(label) { - this.textContent = label; - }, - - /** - * Whether the item is the lead in a selection. Setting this does not update - * the underlying selection model. This is only used for display purpose. - * @type {boolean} - */ - get lead() { - return this.hasAttribute('lead'); - }, - set lead(lead) { - if (lead) { - this.setAttribute('lead', ''); - this.scrollIntoViewIfNeeded(false); - } else { - this.removeAttribute('lead'); - } - }, - - /** - * Called when an element is decorated as a list item. - */ - decorate: function() { - } - }; - - cr.defineProperty(ListItem, 'selected', cr.PropertyKind.BOOL_ATTR); - - return { - ListItem: ListItem - }; -}); diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/listselectionmodel.js b/chrome/browser/resources/bookmark_manager/js/cr/ui/listselectionmodel.js deleted file mode 100644 index ef9bce8..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/ui/listselectionmodel.js +++ /dev/null @@ -1,450 +0,0 @@ -// 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. - -cr.define('cr.ui', function() { - const Event = cr.Event; - const EventTarget = cr.EventTarget; - - /** - * Creates a new selection model that is to be used with lists. This is - * implemented for vertical lists but changing the behavior for horizontal - * lists or icon views is a matter of overriding {@code getItemBefore}, - * {@code getItemAfter}, {@code getItemAbove} as well as {@code getItemBelow}. - * - * @constructor - * @extends {!cr.EventTarget} - */ - function ListSelectionModel(list) { - this.list = list; - this.selectedItems_ = {}; - } - - ListSelectionModel.prototype = { - __proto__: EventTarget.prototype, - - /** - * Returns the item below (y axis) the given element. - * @param {*} item The item to get the item below. - * @return {*} The item below or null if not found. - */ - getItemBelow: function(item) { - return item.nextElementSibling; - }, - - /** - * Returns the item above (y axis) the given element. - * @param {*} item The item to get the item above. - * @return {*} The item below or null if not found. - */ - getItemAbove: function(item) { - return item.previousElementSibling; - }, - - /** - * Returns the item before (x axis) the given element. This returns null - * by default but override this for icon view and horizontal selection - * models. - * - * @param {*} item The item to get the item before. - * @return {*} The item before or null if not found. - */ - getItemBefore: function(item) { - return null; - }, - - /** - * Returns the item after (x axis) the given element. This returns null - * by default but override this for icon view and horizontal selection - * models. - * - * @param {*} item The item to get the item after. - * @return {*} The item after or null if not found. - */ - getItemAfter: function(item) { - return null; - }, - - /** - * Returns the next list item. This is the next logical and should not - * depend on any kind of layout of the list. - * @param {*} item The item to get the next item for. - * @return {*} The next item or null if not found. - */ - getNextItem: function(item) { - return item.nextElementSibling; - }, - - /** - * Returns the prevous list item. This is the previous logical and should - * not depend on any kind of layout of the list. - * @param {*} item The item to get the previous item for. - * @return {*} The previous item or null if not found. - */ - getPreviousItem: function(item) { - return item.previousElementSibling; - }, - - /** - * @return {*} The first item. - */ - getFirstItem: function() { - return this.list.firstElementChild; - }, - - /** - * @return {*} The last item. - */ - getLastItem: function() { - return this.list.lastElementChild; - }, - - /** - * Called by the view when the user does a mousedown or mouseup on the list. - * @param {!Event} e The browser mousedown event. - * @param {*} item The item that was under the mouse pointer, null if none. - */ - handleMouseDownUp: function(e, item) { - var anchorItem = this.anchorItem; - var isDown = e.type == 'mousedown'; - - this.beginChange_(); - - if (!item) { - // On Mac we always clear the selection if the user clicks a blank area. - // On Windows, we only clear the selection if neither Shift nor Ctrl are - // pressed. - if (cr.isMac) { - this.clear(); - } else if (!isDown && !e.shiftKey && !e.ctrlKey) - // Keep anchor and lead items. - this.clearAllSelected_(); - } else { - if (cr.isMac ? e.metaKey : e.ctrlKey) { - // Selection is handled at mouseUp on windows/linux, mouseDown on mac. - if (cr.isMac? isDown : !isDown) { - // toggle the current one and make it anchor item - this.setItemSelected(item, !this.getItemSelected(item)); - this.leadItem = item; - this.anchorItem = item; - } - } else if (e.shiftKey && anchorItem && anchorItem != item) { - // Shift is done in mousedown - if (isDown) { - this.clearAllSelected_(); - this.leadItem = item; - this.selectRange(anchorItem, item); - } - } else { - // Right click for a context menu need to not clear the selection. - var isRightClick = e.button == 2; - - // If the item is selected this is handled in mouseup. - var itemSelected = this.getItemSelected(item); - if ((itemSelected && !isDown || !itemSelected && isDown) && - !(itemSelected && isRightClick)) { - this.clearAllSelected_(); - this.setItemSelected(item, true); - this.leadItem = item; - this.anchorItem = item; - } - } - } - - this.endChange_(); - }, - - /** - * Called by the view when it recieves a keydown event. - * @param {Event} e The keydown event. - */ - handleKeyDown: function(e) { - var newItem = null; - var leadItem = this.leadItem; - var prevent = true; - - // Ctrl/Meta+A - if (e.keyCode == 65 && - (cr.isMac && e.metaKey || !cr.isMac && e.ctrlKey)) { - this.selectAll(); - e.preventDefault(); - return; - } - - // Space - if (e.keyCode == 32) { - if (leadItem != null) { - var selected = this.getItemSelected(leadItem); - if (e.ctrlKey || !selected) { - this.beginChange_(); - this.setItemSelected(leadItem, !selected); - this.endChange_(); - return; - } - } - } - - switch (e.keyIdentifier) { - case 'Home': - newItem = this.getFirstItem(); - break; - case 'End': - newItem = this.getLastItem(); - break; - case 'Up': - newItem = !leadItem ? - this.getLastItem() : this.getItemAbove(leadItem); - break; - case 'Down': - newItem = !leadItem ? - this.getFirstItem() : this.getItemBelow(leadItem); - break; - case 'Left': - newItem = !leadItem ? - this.getLastItem() : this.getItemBefore(leadItem); - break; - case 'Right': - newItem = !leadItem ? - this.getFirstItem() : this.getItemAfter(leadItem); - break; - default: - prevent = false; - } - - if (newItem) { - this.beginChange_(); - - this.leadItem = newItem; - if (e.shiftKey) { - var anchorItem = this.anchorItem; - this.clearAllSelected_(); - if (!anchorItem) { - this.setItemSelected(newItem, true); - this.anchorItem = newItem; - } else { - this.selectRange(anchorItem, newItem); - } - } else if (e.ctrlKey && !cr.isMac) { - // Setting the lead item is done above - // Mac does not allow you to change the lead. - } else { - this.clearAllSelected_(); - this.setItemSelected(newItem, true); - this.anchorItem = newItem; - } - - this.endChange_(); - - if (prevent) - e.preventDefault(); - } - }, - - /** - * @type {!Array} The selected items. - */ - get selectedItems() { - return Object.keys(this.selectedItems_).map(function(uid) { - return this.selectedItems_[uid]; - }, this); - }, - set selectedItems(selectedItems) { - this.beginChange_(); - this.clearAllSelected_(); - for (var i = 0; i < selectedItems.length; i++) { - this.setItemSelected(selectedItems[i], true); - } - this.leadItem = this.anchorItem = selectedItems[0] || null; - this.endChange_(); - }, - - /** - * Convenience getter which returns the first selected item. - * @type {*} - */ - get selectedItem() { - for (var uid in this.selectedItems_) { - return this.selectedItems_[uid]; - } - return null; - }, - set selectedItem(selectedItem) { - this.beginChange_(); - this.clearAllSelected_(); - if (selectedItem) { - this.selectedItems = [selectedItem]; - } else { - this.leadItem = this.anchorItem = null; - } - this.endChange_(); - }, - - /** - * Selects a range of items, starting with {@code start} and ends with - * {@code end}. - * @param {*} start The first item to select. - * @param {*} end The last item to select. - */ - selectRange: function(start, end) { - // Swap if starts comes after end. - if (start.compareDocumentPosition(end) & Node.DOCUMENT_POSITION_PRECEDING) { - var tmp = start; - start = end; - end = tmp; - } - - this.beginChange_(); - - for (var item = start; item != end; item = this.getNextItem(item)) { - this.setItemSelected(item, true); - } - this.setItemSelected(end, true); - - this.endChange_(); - }, - - /** - * Selects all items. - */ - selectAll: function() { - this.selectRange(this.getFirstItem(), this.getLastItem()); - }, - - /** - * Clears the selection - */ - clear: function() { - this.beginChange_(); - this.anchorItem = this.leadItem = null; - this.clearAllSelected_(); - this.endChange_(); - }, - - /** - * Clears the selection and updates the view. - * @private - */ - clearAllSelected_: function() { - for (var uid in this.selectedItems_) { - this.setItemSelected(this.selectedItems_[uid], false); - } - }, - - /** - * Sets the selecte state for an item. - * @param {*} item The item to set the selected state for. - * @param {boolean} b Whether to select the item or not. - */ - setItemSelected: function(item, b) { - var uid = this.list.itemToUid(item); - var oldSelected = uid in this.selectedItems_; - if (oldSelected == b) - return; - - if (b) - this.selectedItems_[uid] = item; - else - delete this.selectedItems_[uid]; - - this.beginChange_(); - - // Changing back? - if (uid in this.changedUids_ && this.changedUids_[uid] == !b) { - delete this.changedUids_[uid]; - } else { - this.changedUids_[uid] = b; - } - - // End change dispatches an event which in turn may update the view. - this.endChange_(); - }, - - /** - * Whether a given item is selected or not. - * @param {*} item The item to check. - * @return {boolean} Whether an item is selected. - */ - getItemSelected: function(item) { - var uid = this.list.itemToUid(item); - return uid in this.selectedItems_; - }, - - /** - * This is used to begin batching changes. Call {@code endChange_} when you - * are done making changes. - * @private - */ - beginChange_: function() { - if (!this.changeCount_) { - this.changeCount_ = 0; - this.changedUids_ = {}; - } - this.changeCount_++; - }, - - /** - * Call this after changes are done and it will dispatch a change event if - * any changes were actually done. - * @private - */ - endChange_: function() { - this.changeCount_--; - if (!this.changeCount_) { - var uids = Object.keys(this.changedUids_); - if (uids.length) { - var e = new Event('change'); - e.changes = uids.map(function(uid) { - return { - uid: uid, - selected: this.changedUids_[uid] - }; - }, this); - this.dispatchEvent(e); - } - delete this.changedUids_; - delete this.changeCount_; - } - }, - - /** - * Called when an item is removed from the lisst. - * @param {cr.ui.ListItem} item The list item that was removed. - */ - remove: function(item) { - if (item == this.leadItem) - this.leadItem = this.getNextItem(item) || this.getPreviousItem(item); - if (item == this.anchorItem) - this.anchorItem = this.getNextItem(item) || this.getPreviousItem(item); - - // Deselect when removing items. - if (this.getItemSelected(item)) - this.setItemSelected(item, false); - }, - - /** - * Called when an item was added to the list. - * @param {cr.ui.ListItem} item The list item to add. - */ - add: function(item) { - // We could (should?) check if the item is selected here and update the - // selection model. - } - }; - - /** - * The anchorItem is used with multiple selection. - * @type {*} - */ - cr.defineProperty(ListSelectionModel, 'anchorItem', cr.PropertyKind.JS, null); - - /** - * The leadItem is used with multiple selection and it is the item that the - * user is moving uysing the arrow keys. - * @type {*} - */ - cr.defineProperty(ListSelectionModel, 'leadItem', cr.PropertyKind.JS, null); - - return { - ListSelectionModel: ListSelectionModel - }; -}); diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/menu.js b/chrome/browser/resources/bookmark_manager/js/cr/ui/menu.js deleted file mode 100644 index 1145d0f..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/ui/menu.js +++ /dev/null @@ -1,157 +0,0 @@ -// 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. - -cr.define('cr.ui', function() { - - const MenuItem = cr.ui.MenuItem; - - /** - * Creates a new menu element. - * @param {Object=} opt_propertyBag Optional properties. - * @constructor - * @extends {HTMLMenuElement} - */ - var Menu = cr.ui.define('menu'); - - Menu.prototype = { - __proto__: HTMLMenuElement.prototype, - - /** - * Initializes the menu element. - */ - decorate: function() { - this.addEventListener('mouseover', this.handleMouseOver_); - this.addEventListener('mouseout', this.handleMouseOut_); - - // Decorate the children as menu items. - var children = this.children; - for (var i = 0, child; child = children[i]; i++) { - cr.ui.decorate(child, MenuItem); - } - }, - - /** - * Walks up the ancestors until a menu item belonging to this menu is found. - * @param {Element} el - * @return {cr.ui.MenuItem} The found menu item or null. - * @private - */ - findMenuItem_: function(el) { - while (el && el.parentNode != this) { - el = el.parentNode; - } - return el; - }, - - /** - * Handles mouseover events and selects the hovered item. - * @param {Event} e The mouseover event. - * @private - */ - handleMouseOver_: function(e) { - var overItem = this.findMenuItem_(e.target); - this.selectedItem = overItem; - }, - - /** - * Handles mouseout events and deselects any selected item. - * @param {Event} e The mouseout event. - * @private - */ - handleMouseOut_: function(e) { - this.selectedItem = null; - }, - - /** - * The index of the selected item. - * @type {boolean} - */ - // getter and default value is defined using cr.defineProperty. - set selectedIndex(selectedIndex) { - if (this.selectedIndex_ != selectedIndex) { - var oldSelectedItem = this.selectedItem; - this.selectedIndex_ = selectedIndex; - if (oldSelectedItem) - oldSelectedItem.selected = false; - var item = this.selectedItem; - if (item) - item.selected = true; - - cr.dispatchSimpleEvent(this, 'change'); - } - }, - - /** - * The selected menu item or null if none. - * @type {cr.ui.MenuItem} - */ - get selectedItem() { - return this.children[this.selectedIndex]; - }, - set selectedItem(item) { - var index = Array.prototype.indexOf.call(this.children, item); - this.selectedIndex = index; - }, - - /** - * This is the function that handles keyboard navigation. This is usually - * called by the element responsible for managing the menu. - * @param {Event} e The keydown event object. - * @return {boolean} Whether the event was handled be the menu. - */ - handleKeyDown: function(e) { - var item = this.selectedItem; - - var self = this; - function selectNextVisible(m) { - var children = self.children; - var len = children.length; - var i = self.selectedIndex; - if (i == -1 && m == -1) { - // Edge case when we need to go the last item fisrt. - i = 0; - } - while (true) { - i = (i + m + len) % len; - item = children[i]; - if (item && !item.isSeparator() && !item.hidden) - break; - } - if (item) - self.selectedIndex = i; - } - - switch (e.keyIdentifier) { - case 'Down': - selectNextVisible(1); - return true; - case 'Up': - selectNextVisible(-1); - return true; - case 'Enter': - case 'U+0020': // Space - if (item) { - if (cr.dispatchSimpleEvent(item, 'activate', true, true)) { - if (item.command) - item.command.execute(); - } - } - return true; - } - - return false; - } - }; - - /** - * The selected menu item. - * @type {number} - */ - cr.defineProperty(Menu, 'selectedIndex', cr.PropertyKind.JS, -1); - - // Export - return { - Menu: Menu - }; -}); diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/menubutton.js b/chrome/browser/resources/bookmark_manager/js/cr/ui/menubutton.js deleted file mode 100644 index cd8defb..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/ui/menubutton.js +++ /dev/null @@ -1,167 +0,0 @@ -// 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. - -cr.define('cr.ui', function() { - const Menu = cr.ui.Menu; - - /** - * Creates a new menu button element. - * @param {Object=} opt_propertyBag Optional properties. - * @constructor - * @extends {HTMLButtonElement} - */ - var MenuButton = cr.ui.define('button'); - - MenuButton.prototype = { - __proto__: HTMLButtonElement.prototype, - - /** - * Initializes the menu button. - */ - decorate: function() { - this.addEventListener('mousedown', this); - this.addEventListener('keydown', this); - - var menu; - if ((menu = this.getAttribute('menu'))) - this.menu = menu; - }, - - /** - * The menu associated with the menu button. - * @type {cr.ui.Menu} - */ - get menu() { - return this.menu_; - }, - set menu(menu) { - if (typeof menu == 'string' && menu[0] == '#') { - menu = this.ownerDocument.getElementById(menu.slice(1)); - cr.ui.decorate(menu, Menu); - } - - this.menu_ = menu; - if (menu) { - if (menu.id) - this.setAttribute('menu', '#' + menu.id); - } - }, - - /** - * Handles event callbacks. - * @param {Event} e The event object. - */ - handleEvent: function(e) { - if (!this.menu) - return; - - switch (e.type) { - case 'mousedown': - if (e.currentTarget == this.ownerDocument) { - if (!this.contains(e.target) && !this.menu.contains(e.target)) - this.hideMenu(); - else - e.preventDefault(); - } else { - if (this.isMenuShown()) { - this.hideMenu(); - } else if (e.button == 0) { // Only show the menu when using left - // mouse button. - this.showMenu(); - // Prevent the button from stealing focus on mousedown. - e.preventDefault(); - } - } - break; - case 'keydown': - this.handleKeyDown(e); - // If the menu is visible we let it handle all the keyboard events. - if (this.isMenuShown() && e.currentTarget == this.ownerDocument) { - this.menu.handleKeyDown(e); - e.preventDefault(); - e.stopPropagation(); - } - break; - - case 'activate': - case 'blur': - this.hideMenu(); - break; - } - }, - - /** - * Shows the menu. - */ - showMenu: function() { - this.menu.style.display = 'block'; - // when the menu is shown we steal all keyboard events. - this.ownerDocument.addEventListener('keydown', this, true); - this.ownerDocument.addEventListener('mousedown', this, true); - this.ownerDocument.addEventListener('blur', this, true); - this.menu.addEventListener('activate', this); - this.positionMenu_(); - }, - - /** - * Hides the menu. - */ - hideMenu: function() { - this.menu.style.display = 'none'; - this.ownerDocument.removeEventListener('keydown', this, true); - this.ownerDocument.removeEventListener('mousedown', this, true); - this.ownerDocument.removeEventListener('blur', this, true); - this.menu.removeEventListener('activate', this); - this.menu.selectedIndex = -1; - }, - - /** - * Whether the menu is shown. - */ - isMenuShown: function() { - return window.getComputedStyle(this.menu).display != 'none'; - }, - - /** - * Positions the menu below the menu button. At this point we do not use any - * advanced positioning logic to ensure the menu fits in the viewport. - * @private - */ - positionMenu_: function() { - var buttonRect = this.getBoundingClientRect(); - this.menu.style.top = buttonRect.bottom + 'px'; - if (getComputedStyle(this).direction == 'rtl') { - var menuRect = this.menu.getBoundingClientRect(); - this.menu.style.left = buttonRect.right - menuRect.width + 'px'; - } else { - this.menu.style.left = buttonRect.left + 'px'; - } - }, - - /** - * Handles the keydown event for the menu button. - */ - handleKeyDown: function(e) { - switch (e.keyIdentifier) { - case 'Down': - case 'Up': - case 'Enter': - case 'U+0020': // Space - if (!this.isMenuShown()) - this.showMenu(); - e.preventDefault(); - break; - case 'Esc': - case 'U+001B': // Maybe this is remote desktop playing a prank? - this.hideMenu(); - break; - } - } - }; - - // Export - return { - MenuButton: MenuButton - }; -}); diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/menuitem.js b/chrome/browser/resources/bookmark_manager/js/cr/ui/menuitem.js deleted file mode 100644 index 5c66f17..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/ui/menuitem.js +++ /dev/null @@ -1,147 +0,0 @@ -// 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. - -cr.define('cr.ui', function() { - const Command = cr.ui.Command; - - /** - * Creates a new menu item element. - * @param {Object=} opt_propertyBag Optional properties. - * @constructor - * @extends {HTMLButtonElement} - */ - var MenuItem = cr.ui.define('button'); - - /** - * Creates a new menu separator element. - * @return {cr.ui.MenuItem} - */ - MenuItem.createSeparator = function() { - var el = cr.doc.createElement('hr'); - MenuItem.decorate(el); - return el; - }; - - MenuItem.prototype = { - __proto__: HTMLButtonElement.prototype, - - /** - * Initializes the menu item. - */ - decorate: function() { - var commandId; - if ((commandId = this.getAttribute('command'))) - this.command = commandId; - - this.addEventListener('mouseup', this.handleMouseUp_); - }, - - /** - * The command associated with this menu item. If this is set to a string - * of the form "#element-id" then the element is looked up in the document - * of the command. - * @type {cr.ui.Command} - */ - command_: null, - get command() { - return this.command_; - }, - set command(command) { - if (this.command_) { - this.command_.removeEventListener('labelChange', this); - this.command_.removeEventListener('disabledChange', this); - this.command_.removeEventListener('hiddenChange', this); - } - - if (typeof command == 'string' && command[0] == '#') { - command = this.ownerDocument.getElementById(command.slice(1)); - cr.ui.decorate(command, Command); - } - - this.command_ = command; - if (command) { - if (command.id) - this.setAttribute('command', '#' + command.id); - - this.label = command.label; - this.disabled = command.disabled; - this.hidden = command.hidden; - - this.command_.addEventListener('labelChange', this); - this.command_.addEventListener('disabledChange', this); - this.command_.addEventListener('hiddenChange', this); - } - }, - - /** - * The text label. - * @type {string} - */ - get label() { - return this.textContent; - }, - set label(label) { - this.textContent = label; - }, - - /** - * @return {boolean} Whether the menu item is a separator. - */ - isSeparator: function() { - return this.tagName == 'HR'; - }, - - /** - * Handles mouseup events. This dispatches an active event and if there - * is an assiciated command then that is executed. - * @param {Event} The mouseup event object. - * @private - */ - handleMouseUp_: function(e) { - if (!this.disabled && !this.isSeparator()) { - // Dispatch command event followed by executing the command object. - if (cr.dispatchSimpleEvent(this, 'activate', true, true)) { - var command = this.command; - if (command) - command.execute(); - } - } - }, - - /** - * Handles changes to the associated command. - * @param {Event} e The event object. - */ - handleEvent: function(e) { - switch (e.type) { - case 'disabledChange': - this.disabled = this.command.disabled; - break; - case 'hiddenChange': - this.hidden = this.command.hidden; - break; - case 'labelChange': - this.label = this.command.label; - break; - } - } - }; - - /** - * Whether the menu item is hidden or not. - * @type {boolean} - */ - cr.defineProperty(MenuItem, 'hidden', cr.PropertyKind.BOOL_ATTR); - - /** - * Whether the menu item is selected or not. - * @type {boolean} - */ - cr.defineProperty(MenuItem, 'selected', cr.PropertyKind.BOOL_ATTR); - - // Export - return { - MenuItem: MenuItem - }; -}); diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/splitter.js b/chrome/browser/resources/bookmark_manager/js/cr/ui/splitter.js deleted file mode 100644 index 4f9510e..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/ui/splitter.js +++ /dev/null @@ -1,154 +0,0 @@ -// 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 implements a splitter element which can be used to resize - * elements in split panes. - * - * The parent of the splitter should be an hbox (display: -webkit-box) with at - * least one previous element sibling. The splitter controls the width of the - * element before it. - * - * <div class=split-pane> - * <div class=left>...</div> - * <div class=splitter></div> - * ... - * </div> - * - */ - -cr.define('cr.ui', function() { - // TODO(arv): Currently this only supports horizontal layout. - // TODO(arv): This ignores min-width and max-width of the elements to the - // right of the splitter. - - /** - * Returns the computed style width of an element. - * @param {!Element} el The element to get the width of. - * @return {number} The width in pixels. - */ - function getComputedWidth(el) { - return parseFloat(el.ownerDocument.defaultView.getComputedStyle(el).width) / - getZoomFactor(el.ownerDocument); - } - - /** - * This uses a WebKit bug to work around the same bug. getComputedStyle does - * not take the page zoom into account so it returns the physical pixels - * instead of the logical pixel size. - * @param {!Document} doc The document to get the page zoom factor for. - * @param {number} The zoom factor of the document. - */ - function getZoomFactor(doc) { - var dummyElement = doc.createElement('div'); - dummyElement.style.cssText = - 'position:absolute;width:100px;height:100px;top:-1000px;overflow:hidden'; - doc.body.appendChild(dummyElement); - var cs = doc.defaultView.getComputedStyle(dummyElement); - var rect = dummyElement.getBoundingClientRect(); - var zoomFactor = parseFloat(cs.width) / 100; - doc.body.removeChild(dummyElement); - return zoomFactor; - } - - /** - * Creates a new splitter element. - * @param {Object=} opt_propertyBag Optional properties. - * @constructor - * @extends {HTMLDivElement} - */ - var Splitter = cr.ui.define('div'); - - Splitter.prototype = { - __proto__: HTMLDivElement.prototype, - - /** - * Initializes the element. - */ - decorate: function() { - this.addEventListener('mousedown', cr.bind(this.handleMouseDown_, this), - true); - }, - - /** - * Starts the dragging of the splitter. - * @param {!Event} e The mouse event that started the drag. - */ - startDrag: function(e) { - if (!this.boundHandleMouseMove_) { - this.boundHandleMouseMove_ = cr.bind(this.handleMouseMove_, this); - this.boundHandleMouseUp_ = cr.bind(this.handleMouseUp_, this); - } - - var doc = this.ownerDocument; - - // Use capturing events on the document to get events when the mouse - // leaves the document. - doc.addEventListener('mousemove',this.boundHandleMouseMove_, true); - doc.addEventListener('mouseup', this.boundHandleMouseUp_, true); - - // Use the computed width style as the base so that we can ignore what - // box sizing the element has. - var leftComponent = this.previousElementSibling; - var computedWidth = getComputedWidth(leftComponent); - this.startX_ = e.clientX; - this.startWidth_ = computedWidth - }, - - /** - * Ends the dragging of the splitter. This fires a "resize" event if the - * size changed. - */ - endDrag: function() { - var doc = this.ownerDocument; - doc.removeEventListener('mousemove', this.boundHandleMouseMove_, true); - doc.removeEventListener('mouseup', this.boundHandleMouseUp_, true); - - // Check if the size changed. - var leftComponent = this.previousElementSibling; - var computedWidth = getComputedWidth(leftComponent); - if (this.startWidth_ != computedWidth) - cr.dispatchSimpleEvent(this, 'resize'); - }, - - /** - * Handles the mousedown event which starts the dragging of the splitter. - * @param {!Event} e The mouse event. - * @private - */ - handleMouseDown_: function(e) { - this.startDrag(e); - // Default action is to start selection and to move focus. - e.preventDefault(); - }, - - /** - * Handles the mousemove event which moves the splitter as the user moves - * the mouse. - * @param {!Event} e The mouse event. - * @private - */ - handleMouseMove_: function(e) { - var leftComponent = this.previousElementSibling; - var rtl = this.ownerDocument.defaultView.getComputedStyle(this). - direction == 'rtl'; - var dirMultiplier = rtl ? -1 : 1; - leftComponent.style.width = this.startWidth_ + - dirMultiplier * (e.clientX - this.startX_) + 'px'; - }, - - /** - * Handles the mouse up event which ends the dragging of the splitter. - * @param {!Event} e The mouse event. - * @private - */ - handleMouseUp_: function(e) { - this.endDrag(); - } - }; - - return { - Splitter: Splitter - } -}); diff --git a/chrome/browser/resources/bookmark_manager/js/cr/ui/tree.js b/chrome/browser/resources/bookmark_manager/js/cr/ui/tree.js deleted file mode 100644 index 9e18321..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr/ui/tree.js +++ /dev/null @@ -1,664 +0,0 @@ -// 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. - -cr.define('cr.ui', function() { - // require cr.ui.define - // require cr.ui.limitInputWidth - - /** - * The number of pixels to indent per level. - * @type {number} - */ - const INDENT = 20; - - /** - * Returns the computed style for an element. - * @param {!Element} el The element to get the computed style for. - * @return {!CSSStyleDeclaration} The computed style. - */ - function getComputedStyle(el) { - return el.ownerDocument.defaultView.getComputedStyle(el); - } - - /** - * Helper function that finds the first ancestor tree item. - * @param {!Element} el The element to start searching from. - * @return {cr.ui.TreeItem} The found tree item or null if not found. - */ - function findTreeItem(el) { - while (el && !(el instanceof TreeItem)) { - el = el.parentNode; - } - return el; - } - - /** - * Creates a new tree element. - * @param {Object=} opt_propertyBag Optional properties. - * @constructor - * @extends {HTMLElement} - */ - var Tree = cr.ui.define('tree'); - - Tree.prototype = { - __proto__: HTMLElement.prototype, - - /** - * Initializes the element. - */ - decorate: function() { - // Make list focusable - if (!this.hasAttribute('tabindex')) - this.tabIndex = 0; - - this.addEventListener('click', this.handleClick); - this.addEventListener('mousedown', this.handleMouseDown); - this.addEventListener('dblclick', this.handleDblClick); - this.addEventListener('keydown', this.handleKeyDown); - }, - - /** - * Returns the tree item that are children of this tree. - */ - get items() { - return this.children; - }, - - /** - * Adds a tree item to the tree. - * @param {!cr.ui.TreeItem} treeItem The item to add. - */ - add: function(treeItem) { - this.addAt(treeItem, 0xffffffff); - }, - - /** - * Adds a tree item at the given index. - * @param {!cr.ui.TreeItem} treeItem The item to add. - * @param {number} index The index where we want to add the item. - */ - addAt: function(treeItem, index) { - this.insertBefore(treeItem, this.children[index]); - treeItem.setDepth_(this.depth + 1); - }, - - /** - * Removes a tree item child. - * @param {!cr.ui.TreeItem} treeItem The tree item to remove. - */ - remove: function(treeItem) { - this.removeChild(treeItem); - }, - - /** - * The depth of the node. This is 0 for the tree itself. - * @type {number} - */ - get depth() { - return 0; - }, - - /** - * Handles click events on the tree and forwards the event to the relevant - * tree items as necesary. - * @param {Event} e The click event object. - */ - handleClick: function(e) { - var treeItem = findTreeItem(e.target); - if (treeItem) - treeItem.handleClick(e); - }, - - handleMouseDown: function(e) { - if (e.button == 2) // right - this.handleClick(e); - }, - - /** - * Handles double click events on the tree. - * @param {Event} e The dblclick event object. - */ - handleDblClick: function(e) { - var treeItem = findTreeItem(e.target); - if (treeItem) - treeItem.expanded = !treeItem.expanded; - }, - - /** - * Handles keydown events on the tree and updates selection and exanding - * of tree items. - * @param {Event} e The click event object. - */ - handleKeyDown: function(e) { - var itemToSelect; - if (e.ctrlKey) - return; - - var item = this.selectedItem; - - var rtl = getComputedStyle(item).direction == 'rtl'; - - switch (e.keyIdentifier) { - case 'Up': - itemToSelect = item ? getPrevious(item) : - this.items[this.items.length - 1]; - break; - case 'Down': - itemToSelect = item ? getNext(item) : - this.items[0]; - break; - case 'Left': - case 'Right': - // Don't let back/forward keyboard shortcuts be used. - if (!cr.isMac && e.altKey || cr.isMac && e.metaKey) - break; - - if (e.keyIdentifier == 'Left' && !rtl || - e.keyIdentifier == 'Right' && rtl) { - if (item.expanded) - item.expanded = false; - else - itemToSelect = findTreeItem(item.parentNode); - } else { - if (!item.expanded) - item.expanded = true; - else - itemToSelect = item.items[0]; - } - break; - case 'Home': - itemToSelect = this.items[0]; - break; - case 'End': - itemToSelect = this.items[this.items.length - 1]; - break; - } - - if (itemToSelect) { - itemToSelect.selected = true; - e.preventDefault(); - } - }, - - /** - * The selected tree item or null if none. - * @type {cr.ui.TreeItem} - */ - get selectedItem() { - return this.selectedItem_ || null; - }, - set selectedItem(item) { - var oldSelectedItem = this.selectedItem_; - if (oldSelectedItem != item) { - // Set the selectedItem_ before deselecting the old item since we only - // want one change when moving between items. - this.selectedItem_ = item; - - if (oldSelectedItem) - oldSelectedItem.selected = false; - - if (item) - item.selected = true; - - cr.dispatchSimpleEvent(this, 'change'); - } - }, - - /** - * @return {!ClientRect} The rect to use for the context menu. - */ - getRectForContextMenu: function() { - // TODO(arv): Add trait support so we can share more code between trees - // and lists. - if (this.selectedItem) - return this.selectedItem.rowElement.getBoundingClientRect(); - return this.getBoundingClientRect(); - } - }; - - /** - * This is used as a blueprint for new tree item elements. - * @type {!HTMLElement} - */ - var treeItemProto = (function() { - var treeItem = cr.doc.createElement('div'); - treeItem.className = 'tree-item'; - treeItem.innerHTML = '<div class=tree-row>' + - '<span class=expand-icon></span>' + - '<span class=tree-label></span>' + - '</div>' + - '<div class=tree-children></div>'; - return treeItem; - })(); - - /** - * Creates a new tree item. - * @param {Object=} opt_propertyBag Optional properties. - * @constructor - * @extends {HTMLElement} - */ - var TreeItem = cr.ui.define(function() { - return treeItemProto.cloneNode(true); - }); - - TreeItem.prototype = { - __proto__: HTMLElement.prototype, - - /** - * Initializes the element. - */ - decorate: function() { - - }, - - /** - * The tree items children. - */ - get items() { - return this.lastElementChild.children; - }, - - /** - * The depth of the tree item. - * @type {number} - */ - depth_: 0, - get depth() { - return this.depth_; - }, - - /** - * Sets the depth. - * @param {number} depth The new depth. - * @private - */ - setDepth_: function(depth) { - if (depth != this.depth_) { - this.rowElement.style.WebkitPaddingStart = Math.max(0, depth - 1) * - INDENT + 'px'; - this.depth_ = depth; - var items = this.items; - for (var i = 0, item; item = items[i]; i++) { - item.setDepth_(depth + 1); - } - } - }, - - /** - * Adds a tree item as a child. - * @param {!cr.ui.TreeItem} child The child to add. - */ - add: function(child) { - this.addAt(child, 0xffffffff); - }, - - /** - * Adds a tree item as a child at a given index. - * @param {!cr.ui.TreeItem} child The child to add. - * @param {number} index The index where to add the child. - */ - addAt: function(child, index) { - this.lastElementChild.insertBefore(child, this.items[index]); - if (this.items.length == 1) - this.hasChildren_ = true; - child.setDepth_(this.depth + 1); - }, - - /** - * Removes a child. - * @param {!cr.ui.TreeItem} child The tree item child to remove. - */ - remove: function(child) { - // If we removed the selected item we should become selected. - var tree = this.tree; - var selectedItem = tree.selectedItem; - if (selectedItem && child.contains(selectedItem)) - this.selected = true; - - this.lastElementChild.removeChild(child); - if (this.items.length == 0) - this.hasChildren_ = false; - }, - - /** - * The parent tree item. - * @type {!cr.ui.Tree|cr.ui.TreeItem} - */ - get parentItem() { - var p = this.parentNode; - while (p && !(p instanceof TreeItem) && !(p instanceof Tree)) { - p = p.parentNode; - } - return p; - }, - - /** - * The tree that the tree item belongs to or null of no added to a tree. - * @type {cr.ui.Tree} - */ - get tree() { - var t = this.parentItem; - while (t && !(t instanceof Tree)) { - t = t.parentItem; - } - return t; - }, - - /** - * Whether the tree item is expanded or not. - * @type {boolean} - */ - get expanded() { - return this.hasAttribute('expanded'); - }, - set expanded(b) { - if (this.expanded == b) - return; - - var treeChildren = this.lastElementChild; - - if (b) { - if (this.mayHaveChildren_) { - this.setAttribute('expanded', ''); - treeChildren.setAttribute('expanded', ''); - cr.dispatchSimpleEvent(this, 'expand', true); - this.scrollIntoViewIfNeeded(false); - } - } else { - var tree = this.tree; - if (tree && !this.selected) { - var oldSelected = tree.selectedItem; - if (oldSelected && this.contains(oldSelected)) - this.selected = true; - } - this.removeAttribute('expanded'); - treeChildren.removeAttribute('expanded'); - cr.dispatchSimpleEvent(this, 'collapse', true); - } - }, - - /** - * Expands all parent items. - */ - reveal: function() { - var pi = this.parentItem; - while (pi && !(pi instanceof Tree)) { - pi.expanded = true; - pi = pi.parentItem; - } - }, - - /** - * The element representing the row that gets highlighted. - * @type {!HTMLElement} - */ - get rowElement() { - return this.firstElementChild; - }, - - /** - * The element containing the label text and the icon. - * @type {!HTMLElement} - */ - get labelElement() { - return this.firstElementChild.lastElementChild; - }, - - /** - * The label text. - * @type {string} - */ - get label() { - return this.labelElement.textContent; - }, - set label(s) { - this.labelElement.textContent = s; - }, - - /** - * The URL for the icon. - * @type {string} - */ - get icon() { - return getComputedStyle(this.labelElement).backgroundImage.slice(4, -1); - }, - set icon(icon) { - return this.labelElement.style.backgroundImage = url(icon); - }, - - /** - * Whether the tree item is selected or not. - * @type {boolean} - */ - get selected() { - return this.hasAttribute('selected'); - }, - set selected(b) { - if (this.selected == b) - return; - var rowItem = this.firstElementChild; - var tree = this.tree; - if (b) { - this.setAttribute('selected', ''); - rowItem.setAttribute('selected', ''); - this.labelElement.scrollIntoViewIfNeeded(false); - if (tree) - tree.selectedItem = this; - } else { - this.removeAttribute('selected'); - rowItem.removeAttribute('selected'); - if (tree && tree.selectedItem == this) - tree.selectedItem = null; - } - }, - - /** - * Whether the tree item has children. - * @type {boolean} - */ - get mayHaveChildren_() { - return this.hasAttribute('may-have-children'); - }, - set mayHaveChildren_(b) { - var rowItem = this.firstElementChild; - if (b) { - this.setAttribute('may-have-children', ''); - rowItem.setAttribute('may-have-children', ''); - } else { - this.removeAttribute('may-have-children'); - rowItem.removeAttribute('may-have-children'); - } - }, - - /** - * Whether the tree item has children. - * @type {boolean} - */ - get hasChildren() { - return !!this.items[0]; - }, - - /** - * Whether the tree item has children. - * @type {boolean} - * @private - */ - set hasChildren_(b) { - var rowItem = this.firstElementChild; - this.setAttribute('has-children', b); - rowItem.setAttribute('has-children', b); - if (b) - this.mayHaveChildren_ = true; - }, - - /** - * Called when the user clicks on a tree item. This is forwarded from the - * cr.ui.Tree. - * @param {Event} e The click event. - */ - handleClick: function(e) { - if (e.target.className == 'expand-icon') - this.expanded = !this.expanded; - else - this.selected = true; - }, - - /** - * Makes the tree item user editable. If the user renamed the item a - * bubbling {@code rename} event is fired. - * @type {boolean} - */ - set editing(editing) { - var oldEditing = this.editing; - if (editing == oldEditing) - return; - - var self = this; - var labelEl = this.labelElement; - var text = this.label; - var input; - - // Handles enter and escape which trigger reset and commit respectively. - function handleKeydown(e) { - // Make sure that the tree does not handle the key. - e.stopPropagation(); - - // Calling tree.focus blurs the input which will make the tree item - // non editable. - switch (e.keyIdentifier) { - case 'U+001B': // Esc - input.value = text; - // fall through - case 'Enter': - self.tree.focus(); - } - } - - function stopPropagation(e) { - e.stopPropagation(); - } - - if (editing) { - this.selected = true; - this.setAttribute('editing', ''); - this.draggable = false; - - // We create an input[type=text] and copy over the label value. When - // the input loses focus we set editing to false again. - input = this.ownerDocument.createElement('input'); - input.value = text; - if (labelEl.firstChild) - labelEl.replaceChild(input, labelEl.firstChild); - else - labelEl.appendChild(input); - - input.addEventListener('keydown', handleKeydown); - input.addEventListener('blur', cr.bind(function() { - this.editing = false; - }, this)); - - // Make sure that double clicks do not expand and collapse the tree - // item. - var eventsToStop = ['mousedown', 'mouseup', 'contextmenu', 'dblclick']; - eventsToStop.forEach(function(type) { - input.addEventListener(type, stopPropagation); - }); - - // Wait for the input element to recieve focus before sizing it. - var rowElement = this.rowElement; - function onFocus() { - input.removeEventListener('focus', onFocus); - // 20 = the padding and border of the tree-row - cr.ui.limitInputWidth(input, rowElement, 20); - } - input.addEventListener('focus', onFocus); - input.focus(); - input.select(); - - this.oldLabel_ = text; - } else { - this.removeAttribute('editing'); - this.draggable = true; - input = labelEl.firstChild; - var value = input.value; - if (/^\s*$/.test(value)) { - labelEl.textContent = this.oldLabel_; - } else { - labelEl.textContent = value; - if (value != this.oldLabel_) { - cr.dispatchSimpleEvent(this, 'rename', true); - } - } - delete this.oldLabel_; - } - }, - - get editing() { - return this.hasAttribute('editing'); - } - }; - - /** - * Helper function that returns the next visible tree item. - * @param {cr.ui.TreeItem} item The tree item. - * @retrun {cr.ui.TreeItem} The found item or null. - */ - function getNext(item) { - if (item.expanded) { - var firstChild = item.items[0]; - if (firstChild) { - return firstChild; - } - } - - return getNextHelper(item); - } - - /** - * Another helper function that returns the next visible tree item. - * @param {cr.ui.TreeItem} item The tree item. - * @retrun {cr.ui.TreeItem} The found item or null. - */ - function getNextHelper(item) { - if (!item) - return null; - - var nextSibling = item.nextElementSibling; - if (nextSibling) { - return nextSibling; - } - return getNextHelper(item.parentItem); - } - - /** - * Helper function that returns the previous visible tree item. - * @param {cr.ui.TreeItem} item The tree item. - * @retrun {cr.ui.TreeItem} The found item or null. - */ - function getPrevious(item) { - var previousSibling = item.previousElementSibling; - return previousSibling ? getLastHelper(previousSibling) : item.parentItem; - } - - /** - * Helper function that returns the last visible tree item in the subtree. - * @param {cr.ui.TreeItem} item The item to find the last visible item for. - * @return {cr.ui.TreeItem} The found item or null. - */ - function getLastHelper(item) { - if (!item) - return null; - if (item.expanded && item.hasChildren) { - var lastChild = item.items[item.items.length - 1]; - return getLastHelper(lastChild); - } - return item; - } - - // Export - return { - Tree: Tree, - TreeItem: TreeItem - }; -}); diff --git a/chrome/browser/resources/bookmark_manager/js/cr_test.html b/chrome/browser/resources/bookmark_manager/js/cr_test.html deleted file mode 100644 index 5d6c16e..0000000 --- a/chrome/browser/resources/bookmark_manager/js/cr_test.html +++ /dev/null @@ -1,231 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<title></title> -<style> - -</style> -<script src="http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"></script> -<script src="cr.js"></script> -<script src="cr/event.js"></script> -<script src="cr/eventtarget.js"></script> -<script> - -goog.require('goog.testing.jsunit'); - -</script> - -</head> -<body> - -<script> - -const EventTarget = cr.EventTarget; - -function testDefineProperty() { - var obj = new EventTarget; - cr.defineProperty(obj, 'test'); - - obj.test = 1; - assertEquals(1, obj.test); - assertEquals(1, obj.test_); -} - -function testDefinePropertyOnClass() { - function C() {} - C.prototype = { - __proto__: EventTarget.prototype - }; - - cr.defineProperty(C, 'test'); - - var obj = new C; - obj.test = 1; - assertEquals(1, obj.test); - assertEquals(1, obj.test_); -} - -function testDefinePropertyWithDefault() { - var obj = new EventTarget; - - cr.defineProperty(obj, 'test', null, 1); - - assertEquals(1, obj.test); - assertEquals(1, obj.test_); - - obj.test = 2; - assertEquals(2, obj.test); - assertEquals(2, obj.test_); -} - -function testDefinePropertyEvent() { - var obj = new EventTarget; - cr.defineProperty(obj, 'test'); - obj.test = 1; - - var count = 0; - function f(e) { - assertEquals('testChange', e.type); - assertEquals('test', e.propertyName); - assertEquals(1, e.oldValue); - assertEquals(2, e.newValue); - count++; - } - - obj.addEventListener('testChange', f); - obj.test = 2; - assertEquals(2, obj.test); - assertEquals('Should have called the property change listener', 1, count); - - obj.test = 2; - assertEquals(1, count); -} - -function testDefinePropertyEventWithDefault() { - var obj = new EventTarget; - cr.defineProperty(obj, 'test', cr.PropertyKind.JS, 1); - - var count = 0; - function f(e) { - assertEquals('testChange', e.type); - assertEquals('test', e.propertyName); - assertEquals(1, e.oldValue); - assertEquals(2, e.newValue); - count++; - } - - obj.addEventListener('testChange', f); - - obj.test = 1; - assertEquals('Should not have called the property change listener', 0, count); - - obj.test = 2; - assertEquals(2, obj.test); - assertEquals('Should have called the property change listener', 1, count); - - obj.test = 2; - assertEquals(1, count); -} - -function testDefinePropertyAttr() { - var obj = document.createElement('div'); - cr.defineProperty(obj, 'test', cr.PropertyKind.ATTR); - - obj.test = 'a'; - assertEquals('a', obj.test); - assertEquals('a', obj.getAttribute('test')); -} - -function testDefinePropertyAttrOnClass() { - var obj = document.createElement('button'); - cr.defineProperty(HTMLButtonElement, 'test', cr.PropertyKind.ATTR); - - obj.test = 'a'; - assertEquals('a', obj.test); - assertEquals('a', obj.getAttribute('test')); -} - -function testDefinePropertyAttrWithDefault() { - var obj = document.createElement('div'); - cr.defineProperty(obj, 'test', cr.PropertyKind.ATTR, 'a'); - - assertEquals('a', obj.test); - assertFalse(obj.hasAttribute('test')); - - obj.test = 'b'; - assertEquals('b', obj.test); - assertEquals('b', obj.getAttribute('test')); -} - -function testDefinePropertyAttrEvent() { - var obj = document.createElement('div'); - cr.defineProperty(obj, 'test', cr.PropertyKind.ATTR); - obj.test = 'a'; - - var count = 0; - function f(e) { - assertEquals('testChange', e.type); - assertEquals('test', e.propertyName); - assertEquals('a', e.oldValue); - assertEquals('b', e.newValue); - count++; - } - - obj.addEventListener('testChange', f); - obj.test = 'b'; - assertEquals('b', obj.test); - assertEquals('Should have called the property change listener', 1, count); - - obj.test = 'b'; - assertEquals(1, count); -} - -function testDefinePropertyAttrEventWithDefault() { - var obj = document.createElement('div'); - cr.defineProperty(obj, 'test', cr.PropertyKind.ATTR, 'a'); - - var count = 0; - function f(e) { - assertEquals('testChange', e.type); - assertEquals('test', e.propertyName); - assertEquals('a', e.oldValue); - assertEquals('b', e.newValue); - count++; - } - - obj.addEventListener('testChange', f); - - obj.test = 'a'; - assertEquals('Should not have called the property change listener', 0, count); - - obj.test = 'b'; - assertEquals('b', obj.test); - assertEquals('Should have called the property change listener', 1, count); - - obj.test = 'b'; - assertEquals(1, count); -} - -function testDefinePropertyBoolAttr() { - var obj = document.createElement('div'); - cr.defineProperty(obj, 'test', cr.PropertyKind.BOOL_ATTR); - - assertFalse(obj.test); - assertFalse(obj.hasAttribute('test')); - - obj.test = true; - assertTrue(obj.test); - assertTrue(obj.hasAttribute('test')); - - obj.test = false; - assertFalse(obj.test); - assertFalse(obj.hasAttribute('test')); -} - -function testDefinePropertyBoolAttrEvent() { - var obj = document.createElement('div'); - cr.defineProperty(obj, 'test', cr.PropertyKind.BOOL_ATTR); - - var count = 0; - function f(e) { - assertEquals('testChange', e.type); - assertEquals('test', e.propertyName); - assertEquals(false, e.oldValue); - assertEquals(true, e.newValue); - count++; - } - - obj.addEventListener('testChange', f); - obj.test = true; - assertTrue(obj.test); - assertEquals('Should have called the property change listener', 1, count); - - obj.test = true; - assertEquals(1, count); -} - - -</script> - -</body> -</html> diff --git a/chrome/browser/resources/bookmark_manager/js/i18ntemplate.js b/chrome/browser/resources/bookmark_manager/js/i18ntemplate.js deleted file mode 100644 index 8166ddc..0000000 --- a/chrome/browser/resources/bookmark_manager/js/i18ntemplate.js +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @fileoverview This is a simple template engine inspired by JsTemplates - * optimized for i18n. - * - * It currently supports two handlers: - * - * * i18n-content which sets the textContent of the element - * - * <span i18n-content="myContent"></span> - * i18nTemplate.process(element, {'myContent': 'Content'}); - * - * * i18n-values is a list of attribute-value or property-value pairs. - * Properties are prefixed with a '.' and can contain nested properties. - * - * <span i18n-values="title:myTitle;.style.fontSize:fontSize"></span> - * i18nTemplate.process(element, { - * 'myTitle': 'Title', - * 'fontSize': '13px' - * }); - */ - -var i18nTemplate = (function() { - /** - * This provides the handlers for the templating engine. The key is used as - * the attribute name and the value is the function that gets called for every - * single node that has this attribute. - * @type {Object} - */ - var handlers = { - /** - * This handler sets the textContent of the element. - */ - 'i18n-content': function(element, attributeValue, obj) { - element.textContent = obj[attributeValue]; - }, - - /** - * This is used to set HTML attributes and DOM properties,. The syntax is: - * attributename:key; - * .domProperty:key; - * .nested.dom.property:key - */ - 'i18n-values': function(element, attributeValue, obj) { - var parts = attributeValue.replace(/\s/g, '').split(/;/); - for (var j = 0; j < parts.length; j++) { - var a = parts[j].match(/^([^:]+):(.+)$/); - if (a) { - var propName = a[1]; - var propExpr = a[2]; - - // Ignore missing properties - if (propExpr in obj) { - var value = obj[propExpr]; - if (propName.charAt(0) == '.') { - var path = propName.slice(1).split('.'); - var object = element; - while (object && path.length > 1) { - object = object[path.shift()]; - } - if (object) { - object[path] = value; - // In case we set innerHTML (ignoring others) we need to - // recursively check the content - if (path == 'innerHTML') { - process(element, obj); - } - } - } else { - element.setAttribute(propName, value); - } - } else { - console.warn('i18n-values: Missing value for "' + propExpr + '"'); - } - } - } - } - }; - - var attributeNames = []; - for (var key in handlers) { - attributeNames.push(key); - } - var selector = '[' + attributeNames.join('],[') + ']'; - - /** - * Processes a DOM tree with the {@code obj} map. - */ - function process(node, obj) { - var elements = node.querySelectorAll(selector); - for (var element, i = 0; element = elements[i]; i++) { - for (var j = 0; j < attributeNames.length; j++) { - var name = attributeNames[j]; - var att = element.getAttribute(name); - if (att != null) { - handlers[name](element, att, obj); - } - } - } - } - - return { - process: process - }; -})(); diff --git a/chrome/browser/resources/bookmark_manager/js/localstrings.js b/chrome/browser/resources/bookmark_manager/js/localstrings.js deleted file mode 100644 index 86f888b..0000000 --- a/chrome/browser/resources/bookmark_manager/js/localstrings.js +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2009-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. - -// TODO(arv): Namespace and share code with DOMUI - -/** - * The local strings get injected into the page usig a varaible named - * {@code templateData}. This class provides a simpler interface to access those - * strings. - * @constructor - */ -function LocalStrings() { -} - -LocalStrings.prototype = { - - /** - * The template data object. - * @type {Object} - */ - templateData: null, - - /** - * Gets a localized string by its id. - * @param {string} s The id of the string we want. - * @return {string} The localized string. - */ - getString: function(id) { - return this.templateData[id] || ''; - }, - - /** - * Returns a formatted localized string where all %s contents are replaced - * by the second argument and where $1 to $9 are replaced by the second to - * tenths arguments. - * @param {string} id The ID of the string we want. - * @param {string} v The string to include in the formatted string. - * @param {...string} The extra values to include in the fomatted output. - * @return {string} The formatted string. - */ - getStringF: function(id, v, var_args) { - // The localized messages should contain $n but they also use %s from time - // to time so we support both until all the messages have been unified. - var s = this.getString(id); - var args = arguments; - return s.replace(/%s|\$[$1-9]/g, function(m) { - if (m == '%s') - return v; - if (m == '$$') - return '$'; - return args[m[1]]; - }); - } -}; diff --git a/chrome/browser/resources/bookmark_manager/js/util.js b/chrome/browser/resources/bookmark_manager/js/util.js deleted file mode 100644 index 3fef5d2..0000000 --- a/chrome/browser/resources/bookmark_manager/js/util.js +++ /dev/null @@ -1,57 +0,0 @@ -// 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. - -/** - * The global object. - * @param {!Object} - */ -const global = this; - -/** - * Alias for document.getElementById. - * @param {string} id The ID of the element to find. - * @return {HTMLElement} The found element or null if not found. - */ -function $(id) { - return document.getElementById(id); -} - -/** - * Calls chrome.send with a callback and restores the original afterwards. - * @param {string} name The name of the message to send. - * @param {!Array} params The parameters to send. - * @param {string} callbackName The name of the function that the backend calls. - * @param {!Function} The function to call. - */ -function chromeSend(name, params, callbackName, callback) { - var old = global[callbackName]; - global[callbackName] = function() { - // restore - global[callbackName] = old; - - var args = Array.prototype.slice.call(arguments); - return callback.apply(global, args); - }; - chrome.send(name, params); -} - - -/** - * Generates a CSS url string. - * @param {string} s The URL to generate the CSS url for. - * @return {string} The CSS url string. - */ -function url(s) { - // http://www.w3.org/TR/css3-values/#uris - // Parentheses, commas, whitespace characters, single quotes (') and double - // quotes (") appearing in a URI must be escaped with a backslash - var s2 = s.replace(/(\(|\)|\,|\s|\'|\"|\\)/g, '\\$1'); - // WebKit has a bug when it comes to URLs that end with \ - // https://bugs.webkit.org/show_bug.cgi?id=28885 - if (/\\\\$/.test(s2)) { - // Add a space to work around the WebKit bug. - s2 += ' '; - } - return 'url("' + s2 + '")'; -} |