customcolorpalette.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright 2007 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview A color palette with a button for adding additional colors
  16. * manually.
  17. *
  18. */
  19. goog.provide('goog.ui.CustomColorPalette');
  20. goog.require('goog.color');
  21. goog.require('goog.dom');
  22. goog.require('goog.dom.TagName');
  23. goog.require('goog.dom.classlist');
  24. goog.require('goog.ui.ColorPalette');
  25. goog.require('goog.ui.Component');
  26. /**
  27. * A custom color palette is a grid of color swatches and a button that allows
  28. * the user to add additional colors to the palette
  29. *
  30. * @param {Array<string>} initColors Array of initial colors to populate the
  31. * palette with.
  32. * @param {goog.ui.PaletteRenderer=} opt_renderer Renderer used to render or
  33. * decorate the palette; defaults to {@link goog.ui.PaletteRenderer}.
  34. * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper, used for
  35. * document interaction.
  36. * @constructor
  37. * @extends {goog.ui.ColorPalette}
  38. * @final
  39. */
  40. goog.ui.CustomColorPalette = function(initColors, opt_renderer, opt_domHelper) {
  41. goog.ui.ColorPalette.call(this, initColors, opt_renderer, opt_domHelper);
  42. this.setSupportedState(goog.ui.Component.State.OPENED, true);
  43. };
  44. goog.inherits(goog.ui.CustomColorPalette, goog.ui.ColorPalette);
  45. /**
  46. * Returns an array of DOM nodes for each color, and an additional cell with a
  47. * '+'.
  48. * @return {!Array<Node>} Array of div elements.
  49. * @override
  50. */
  51. goog.ui.CustomColorPalette.prototype.createColorNodes = function() {
  52. /** @desc Hover caption for the button that allows the user to add a color. */
  53. var MSG_CLOSURE_CUSTOM_COLOR_BUTTON = goog.getMsg('Add a color');
  54. var nl = goog.ui.CustomColorPalette.base(this, 'createColorNodes');
  55. nl.push(
  56. goog.dom.createDom(
  57. goog.dom.TagName.DIV, {
  58. 'class': goog.getCssName('goog-palette-customcolor'),
  59. 'title': MSG_CLOSURE_CUSTOM_COLOR_BUTTON
  60. },
  61. '+'));
  62. return nl;
  63. };
  64. /**
  65. * @override
  66. * @param {goog.events.Event} e Mouse or key event that triggered the action.
  67. * @return {boolean} True if the action was allowed to proceed, false otherwise.
  68. */
  69. goog.ui.CustomColorPalette.prototype.performActionInternal = function(e) {
  70. var item = /** @type {Element} */ (this.getHighlightedItem());
  71. if (item) {
  72. if (goog.dom.classlist.contains(
  73. item, goog.getCssName('goog-palette-customcolor'))) {
  74. // User activated the special "add custom color" swatch.
  75. this.promptForCustomColor();
  76. } else {
  77. // User activated a normal color swatch.
  78. this.setSelectedItem(item);
  79. return this.dispatchEvent(goog.ui.Component.EventType.ACTION);
  80. }
  81. }
  82. return false;
  83. };
  84. /**
  85. * Prompts the user to enter a custom color. Currently uses a window.prompt
  86. * but could be updated to use a dialog box with a WheelColorPalette.
  87. */
  88. goog.ui.CustomColorPalette.prototype.promptForCustomColor = function() {
  89. /** @desc Default custom color dialog. */
  90. var MSG_CLOSURE_CUSTOM_COLOR_PROMPT = goog.getMsg(
  91. 'Input custom color, i.e. pink, #F00, #D015FF or rgb(100, 50, 25)');
  92. // A CustomColorPalette is considered "open" while the color selection prompt
  93. // is open. Enabling state transition events for the OPENED state and
  94. // listening for OPEN events allows clients to save the selection before
  95. // it is destroyed (see e.g. bug 1064701).
  96. var response = null;
  97. this.setOpen(true);
  98. if (this.isOpen()) {
  99. // The OPEN event wasn't canceled; prompt for custom color.
  100. response = window.prompt(MSG_CLOSURE_CUSTOM_COLOR_PROMPT, '#FFFFFF');
  101. this.setOpen(false);
  102. }
  103. if (!response) {
  104. // The user hit cancel
  105. return;
  106. }
  107. var color;
  108. try {
  109. color = goog.color.parse(response).hex;
  110. } catch (er) {
  111. /** @desc Alert message sent when the input string is not a valid color. */
  112. var MSG_CLOSURE_CUSTOM_COLOR_INVALID_INPUT = goog.getMsg(
  113. 'ERROR: "{$color}" is not a valid color.', {'color': response});
  114. alert(MSG_CLOSURE_CUSTOM_COLOR_INVALID_INPUT);
  115. return;
  116. }
  117. // TODO(user): This is relatively inefficient. Consider adding
  118. // functionality to palette to add individual items after render time.
  119. var colors = this.getColors();
  120. colors.push(color);
  121. this.setColors(colors);
  122. // Set the selected color to the new color and notify listeners of the action.
  123. this.setSelectedColor(color);
  124. this.dispatchEvent(goog.ui.Component.EventType.ACTION);
  125. };