UnicodeBidiDirection.js.flow 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /**
  2. * Copyright (c) 2013-present, Facebook, Inc.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @providesModule UnicodeBidiDirection
  8. * @typechecks
  9. * @flow
  10. */
  11. /**
  12. * Constants to represent text directionality
  13. *
  14. * Also defines a *global* direciton, to be used in bidi algorithms as a
  15. * default fallback direciton, when no better direction is found or provided.
  16. *
  17. * NOTE: Use `setGlobalDir()`, or update `initGlobalDir()`, to set the initial
  18. * global direction value based on the application.
  19. *
  20. * Part of the implementation of Unicode Bidirectional Algorithm (UBA)
  21. * Unicode Standard Annex #9 (UAX9)
  22. * http://www.unicode.org/reports/tr9/
  23. */
  24. 'use strict';
  25. const invariant = require('./invariant');
  26. export type BidiDirection = 'LTR' | 'RTL' | 'NEUTRAL';
  27. export type HTMLDir = 'ltr' | 'rtl';
  28. const NEUTRAL = 'NEUTRAL'; // No strong direction
  29. const LTR = 'LTR'; // Left-to-Right direction
  30. const RTL = 'RTL'; // Right-to-Left direction
  31. let globalDir: ?BidiDirection = null;
  32. // == Helpers ==
  33. /**
  34. * Check if a directionality value is a Strong one
  35. */
  36. function isStrong(dir: BidiDirection): boolean {
  37. return dir === LTR || dir === RTL;
  38. }
  39. /**
  40. * Get string value to be used for `dir` HTML attribute or `direction` CSS
  41. * property.
  42. */
  43. function getHTMLDir(dir: BidiDirection): HTMLDir {
  44. invariant(isStrong(dir), '`dir` must be a strong direction to be converted to HTML Direction');
  45. return dir === LTR ? 'ltr' : 'rtl';
  46. }
  47. /**
  48. * Get string value to be used for `dir` HTML attribute or `direction` CSS
  49. * property, but returns null if `dir` has same value as `otherDir`.
  50. * `null`.
  51. */
  52. function getHTMLDirIfDifferent(dir: BidiDirection, otherDir: BidiDirection): ?HTMLDir {
  53. invariant(isStrong(dir), '`dir` must be a strong direction to be converted to HTML Direction');
  54. invariant(isStrong(otherDir), '`otherDir` must be a strong direction to be converted to HTML Direction');
  55. return dir === otherDir ? null : getHTMLDir(dir);
  56. }
  57. // == Global Direction ==
  58. /**
  59. * Set the global direction.
  60. */
  61. function setGlobalDir(dir: BidiDirection): void {
  62. globalDir = dir;
  63. }
  64. /**
  65. * Initialize the global direction
  66. */
  67. function initGlobalDir(): void {
  68. setGlobalDir(LTR);
  69. }
  70. /**
  71. * Get the global direction
  72. */
  73. function getGlobalDir(): BidiDirection {
  74. if (!globalDir) {
  75. this.initGlobalDir();
  76. }
  77. invariant(globalDir, 'Global direction not set.');
  78. return globalDir;
  79. }
  80. const UnicodeBidiDirection = {
  81. // Values
  82. NEUTRAL,
  83. LTR,
  84. RTL,
  85. // Helpers
  86. isStrong,
  87. getHTMLDir,
  88. getHTMLDirIfDifferent,
  89. // Global Direction
  90. setGlobalDir,
  91. initGlobalDir,
  92. getGlobalDir
  93. };
  94. module.exports = UnicodeBidiDirection;