loremipsum.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. // Copyright 2008 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 plugin that fills the field with lorem ipsum text when it's
  16. * empty and does not have the focus. Applies to both editable and uneditable
  17. * fields.
  18. *
  19. * @author nicksantos@google.com (Nick Santos)
  20. */
  21. goog.provide('goog.editor.plugins.LoremIpsum');
  22. goog.require('goog.asserts');
  23. goog.require('goog.dom');
  24. goog.require('goog.editor.Command');
  25. goog.require('goog.editor.Field');
  26. goog.require('goog.editor.Plugin');
  27. goog.require('goog.editor.node');
  28. goog.require('goog.functions');
  29. goog.require('goog.html.SafeHtml');
  30. goog.require('goog.userAgent');
  31. /**
  32. * A plugin that manages lorem ipsum state of editable fields.
  33. * @param {string} message The lorem ipsum message.
  34. * @constructor
  35. * @extends {goog.editor.Plugin}
  36. * @final
  37. */
  38. goog.editor.plugins.LoremIpsum = function(message) {
  39. goog.editor.Plugin.call(this);
  40. /**
  41. * The lorem ipsum message.
  42. * @type {string}
  43. * @private
  44. */
  45. this.message_ = message;
  46. };
  47. goog.inherits(goog.editor.plugins.LoremIpsum, goog.editor.Plugin);
  48. /** @override */
  49. goog.editor.plugins.LoremIpsum.prototype.getTrogClassId =
  50. goog.functions.constant('LoremIpsum');
  51. /** @override */
  52. goog.editor.plugins.LoremIpsum.prototype.activeOnUneditableFields =
  53. goog.functions.TRUE;
  54. /**
  55. * Whether the field is currently filled with lorem ipsum text.
  56. * @type {boolean}
  57. * @private
  58. */
  59. goog.editor.plugins.LoremIpsum.prototype.usingLorem_ = false;
  60. /**
  61. * Handles queryCommandValue.
  62. * @param {string} command The command to query.
  63. * @return {boolean} The result.
  64. * @override
  65. */
  66. goog.editor.plugins.LoremIpsum.prototype.queryCommandValue = function(command) {
  67. return command == goog.editor.Command.USING_LOREM && this.usingLorem_;
  68. };
  69. /**
  70. * Handles execCommand.
  71. * @param {string} command The command to execute.
  72. * Should be CLEAR_LOREM or UPDATE_LOREM.
  73. * @param {*=} opt_placeCursor Whether to place the cursor in the field
  74. * after clearing lorem. Should be a boolean.
  75. * @override
  76. */
  77. goog.editor.plugins.LoremIpsum.prototype.execCommand = function(
  78. command, opt_placeCursor) {
  79. if (command == goog.editor.Command.CLEAR_LOREM) {
  80. this.clearLorem_(!!opt_placeCursor);
  81. } else if (command == goog.editor.Command.UPDATE_LOREM) {
  82. this.updateLorem_();
  83. }
  84. };
  85. /** @override */
  86. goog.editor.plugins.LoremIpsum.prototype.isSupportedCommand = function(
  87. command) {
  88. return command == goog.editor.Command.CLEAR_LOREM ||
  89. command == goog.editor.Command.UPDATE_LOREM ||
  90. command == goog.editor.Command.USING_LOREM;
  91. };
  92. /**
  93. * Set the lorem ipsum text in a goog.editor.Field if needed.
  94. * @private
  95. */
  96. goog.editor.plugins.LoremIpsum.prototype.updateLorem_ = function() {
  97. // Try to apply lorem ipsum if:
  98. // 1) We have lorem ipsum text
  99. // 2) There's not a dialog open, as that screws
  100. // with the dialog's ability to properly restore the selection
  101. // on dialog close (since the DOM nodes would get clobbered in FF)
  102. // 3) We're not using lorem already
  103. // 4) The field is not currently active (doesn't have focus).
  104. var fieldObj = this.getFieldObject();
  105. if (!this.usingLorem_ && !fieldObj.inModalMode() &&
  106. goog.editor.Field.getActiveFieldId() != fieldObj.id) {
  107. var field = fieldObj.getElement();
  108. if (!field) {
  109. // Fallback on the original element. This is needed by
  110. // fields managed by click-to-edit.
  111. field = fieldObj.getOriginalElement();
  112. }
  113. goog.asserts.assert(field);
  114. if (goog.editor.node.isEmpty(field)) {
  115. this.usingLorem_ = true;
  116. // Save the old font style so it can be restored when we
  117. // clear the lorem ipsum style.
  118. this.oldFontStyle_ = field.style.fontStyle;
  119. field.style.fontStyle = 'italic';
  120. fieldObj.setSafeHtml(
  121. true, goog.html.SafeHtml.htmlEscapePreservingNewlines(this.message_),
  122. true);
  123. }
  124. }
  125. };
  126. /**
  127. * Clear an EditableField's lorem ipsum and put in initial text if needed.
  128. *
  129. * If using click-to-edit mode (where Trogedit manages whether the field
  130. * is editable), this works for both editable and uneditable fields.
  131. *
  132. * TODO(user): Is this really necessary? See TODO below.
  133. * @param {boolean=} opt_placeCursor Whether to place the cursor in the field
  134. * after clearing lorem.
  135. * @private
  136. */
  137. goog.editor.plugins.LoremIpsum.prototype.clearLorem_ = function(
  138. opt_placeCursor) {
  139. // Don't mess with lorem state when a dialog is open as that screws
  140. // with the dialog's ability to properly restore the selection
  141. // on dialog close (since the DOM nodes would get clobbered)
  142. var fieldObj = this.getFieldObject();
  143. if (this.usingLorem_ && !fieldObj.inModalMode()) {
  144. var field = fieldObj.getElement();
  145. if (!field) {
  146. // Fallback on the original element. This is needed by
  147. // fields managed by click-to-edit.
  148. field = fieldObj.getOriginalElement();
  149. }
  150. goog.asserts.assert(field);
  151. this.usingLorem_ = false;
  152. field.style.fontStyle = this.oldFontStyle_;
  153. fieldObj.setSafeHtml(true, null, true);
  154. // TODO(nicksantos): I'm pretty sure that this is a hack, but talk to
  155. // Julie about why this is necessary and what to do with it. Really,
  156. // we need to figure out where it's necessary and remove it where it's
  157. // not. Safari never places the cursor on its own willpower.
  158. if (opt_placeCursor && fieldObj.isLoaded()) {
  159. if (goog.userAgent.WEBKIT) {
  160. goog.dom.getOwnerDocument(fieldObj.getElement()).body.focus();
  161. fieldObj.focusAndPlaceCursorAtStart();
  162. } else if (goog.userAgent.OPERA) {
  163. fieldObj.placeCursorAtStart();
  164. }
  165. }
  166. }
  167. };