spacestabhandler.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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 Editor plugin to handle tab keys not in lists to add 4 spaces.
  16. *
  17. * @author robbyw@google.com (Robby Walker)
  18. */
  19. goog.provide('goog.editor.plugins.SpacesTabHandler');
  20. goog.require('goog.dom.TagName');
  21. goog.require('goog.editor.plugins.AbstractTabHandler');
  22. goog.require('goog.editor.range');
  23. /**
  24. * Plugin to handle tab keys when not in lists to add 4 spaces.
  25. * @constructor
  26. * @extends {goog.editor.plugins.AbstractTabHandler}
  27. * @final
  28. */
  29. goog.editor.plugins.SpacesTabHandler = function() {
  30. goog.editor.plugins.AbstractTabHandler.call(this);
  31. };
  32. goog.inherits(
  33. goog.editor.plugins.SpacesTabHandler,
  34. goog.editor.plugins.AbstractTabHandler);
  35. /** @override */
  36. goog.editor.plugins.SpacesTabHandler.prototype.getTrogClassId = function() {
  37. return 'SpacesTabHandler';
  38. };
  39. /** @override */
  40. goog.editor.plugins.SpacesTabHandler.prototype.handleTabKey = function(e) {
  41. var dh = this.getFieldDomHelper();
  42. var range = this.getFieldObject().getRange();
  43. if (!goog.editor.range.intersectsTag(range, goog.dom.TagName.LI)) {
  44. // In the shift + tab case we don't want to insert spaces, but we don't
  45. // want focus to move either so skip the spacing logic and just prevent
  46. // default.
  47. if (!e.shiftKey) {
  48. // Not in a list but we want to insert 4 spaces.
  49. // Stop change events while we make multiple field changes.
  50. this.getFieldObject().stopChangeEvents(true, true);
  51. // Inserting nodes below completely messes up the selection, doing the
  52. // deletion here before it's messed up. Only delete if text is selected,
  53. // otherwise we would remove the character to the right of the cursor.
  54. if (!range.isCollapsed()) {
  55. dh.getDocument().execCommand('delete', false, null);
  56. // Safari 3 has some DOM exceptions if we don't reget the range here,
  57. // doing it all the time just to be safe.
  58. range = this.getFieldObject().getRange();
  59. }
  60. // Emulate tab by removing selection and inserting 4 spaces
  61. // Two breaking spaces in a row can be collapsed by the browser into one
  62. // space. Inserting the string below because it is guaranteed to never
  63. // collapse to less than four spaces, regardless of what is adjacent to
  64. // the inserted spaces. This might make line wrapping slightly
  65. // sub-optimal around a grouping of non-breaking spaces.
  66. var elem =
  67. dh.createDom(goog.dom.TagName.SPAN, null, '\u00a0\u00a0 \u00a0');
  68. elem = range.insertNode(elem, false);
  69. this.getFieldObject().dispatchChange();
  70. goog.editor.range.placeCursorNextTo(elem, false);
  71. this.getFieldObject().dispatchSelectionChangeEvent();
  72. }
  73. e.preventDefault();
  74. return true;
  75. }
  76. return false;
  77. };