d2-ui
Version:
156 lines (137 loc) • 10 kB
JavaScript
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @typechecks
*
*/
/**
* Basic (stateless) API for text direction detection
*
* Part of our implementation of Unicode Bidirectional Algorithm (UBA)
* Unicode Standard Annex #9 (UAX9)
* http://www.unicode.org/reports/tr9/
*/
;
var UnicodeBidiDirection = require('./UnicodeBidiDirection');
var invariant = require('./invariant');
/**
* RegExp ranges of characters with a *Strong* Bidi_Class value.
*
* Data is based on DerivedBidiClass.txt in UCD version 7.0.0.
*
* NOTE: For performance reasons, we only support Unicode's
* Basic Multilingual Plane (BMP) for now.
*/
var RANGE_BY_BIDI_TYPE = {
L: 'A-Za-zªµºÀ-ÖØ-öø-ƺƻ' + 'Ƽ-ƿǀ-ǃDŽ-ʓʔʕ-ʯʰ-ʸ' + 'ʻ-ˁː-ˑˠ-ˤˮͰ-ͳͶ-ͷ' + 'ͺͻ-ͽͿΆΈ-ΊΌΎ-Ρ' + 'Σ-ϵϷ-ҁ҂Ҋ-ԯԱ-Ֆՙ' + '՚-՟ա-և։ःऄ-हऻऽ' + 'ा-ीॉ-ौॎ-ॏॐक़-ॡ।-॥' + '०-९॰ॱॲ-ঀং-ঃঅ-ঌ' + 'এ-ঐও-নপ-রলশ-হঽ' + 'া-ীে-ৈো-ৌৎৗড়-ঢ়' + 'য়-ৡ০-৯ৰ-ৱ৴-৹৺ਃ' + 'ਅ-ਊਏ-ਐਓ-ਨਪ-ਰਲ-ਲ਼' + 'ਵ-ਸ਼ਸ-ਹਾ-ੀਖ਼-ੜਫ਼੦-੯' + 'ੲ-ੴઃઅ-ઍએ-ઑઓ-નપ-ર' + 'લ-ળવ-હઽા-ીૉો-ૌૐ' + 'ૠ-ૡ૦-૯૰ଂ-ଃଅ-ଌଏ-ଐ' + 'ଓ-ନପ-ରଲ-ଳଵ-ହଽାୀ' + 'େ-ୈୋ-ୌୗଡ଼-ଢ଼ୟ-ୡ୦-୯' + '୰ୱ୲-୷ஃஅ-ஊஎ-ஐஒ-க' + 'ங-சஜஞ-டண-தந-பம-ஹ' + 'ா-ிு-ூெ-ைொ-ௌௐௗ' + '௦-௯௰-௲ఁ-ఃఅ-ఌఎ-ఐ' + 'ఒ-నప-హఽు-ౄౘ-ౙౠ-ౡ' + '౦-౯౿ಂ-ಃಅ-ಌಎ-ಐಒ-ನ' + 'ಪ-ಳವ-ಹಽಾಿೀ-ೄೆ' + 'ೇ-ೈೊ-ೋೕ-ೖೞೠ-ೡ೦-೯' + 'ೱ-ೲം-ഃഅ-ഌഎ-ഐഒ-ഺഽ' + 'ാ-ീെ-ൈൊ-ൌൎൗൠ-ൡ' + '൦-൯൰-൵൹ൺ-ൿං-ඃඅ-ඖ' + 'ක-නඳ-රලව-ෆා-ෑෘ-ෟ' + '෦-෯ෲ-ෳ෴ก-ะา-ำเ-ๅ' + 'ๆ๏๐-๙๚-๛ກ-ຂຄງ-ຈ' + 'ຊຍດ-ທນ-ຟມ-ຣລວ' + 'ສ-ຫອ-ະາ-ຳຽເ-ໄໆ' + '໐-໙ໜ-ໟༀ༁-༃༄-༒༓༔' + '༕-༗༚-༟༠-༩༪-༳༴༶༸' + '༾-༿ཀ-ཇཉ-ཬཿ྅ྈ-ྌ' + '྾-࿅࿇-࿌࿎-࿏࿐-࿔࿕-࿘' + '࿙-࿚က-ဪါ-ာေးျ-ြဿ' + '၀-၉၊-၏ၐ-ၕၖ-ၗၚ-ၝၡ' + 'ၢ-ၤၥ-ၦၧ-ၭၮ-ၰၵ-ႁ' + 'ႃ-ႄႇ-ႌႎႏ႐-႙ႚ-ႜ' + '႞-႟Ⴀ-ჅჇჍა-ჺ჻ჼ' + 'ჽ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈ' + 'ኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅ' + 'ወ-ዖዘ-ጐጒ-ጕጘ-ፚ፠-፨' + '፩-፼ᎀ-ᎏᎠ-Ᏼᐁ-ᙬ᙭-᙮' + 'ᙯ-ᙿᚁ-ᚚᚠ-ᛪ᛫-᛭ᛮ-ᛰ' + 'ᛱ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱ᜵-᜶' + 'ᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳាើ-ៅ' + 'ះ-ៈ។-៖ៗ៘-៚ៜ០-៩' + '᠐-᠙ᠠ-ᡂᡃᡄ-ᡷᢀ-ᢨᢪ' + 'ᢰ-ᣵᤀ-ᤞᤣ-ᤦᤩ-ᤫᤰ-ᤱ' + 'ᤳ-ᤸ᥆-᥏ᥐ-ᥭᥰ-ᥴᦀ-ᦫ' + 'ᦰ-ᧀᧁ-ᧇᧈ-ᧉ᧐-᧙᧚ᨀ-ᨖ' + 'ᨙ-ᨚ᨞-᨟ᨠ-ᩔᩕᩗᩡᩣ-ᩤ' + 'ᩭ-ᩲ᪀-᪉᪐-᪙᪠-᪦ᪧ᪨-᪭' + 'ᬄᬅ-ᬳᬵᬻᬽ-ᭁᭃ-᭄ᭅ-ᭋ' + '᭐-᭙᭚-᭠᭡-᭪᭴-᭼ᮂᮃ-ᮠ' + 'ᮡᮦ-ᮧ᮪ᮮ-ᮯ᮰-᮹ᮺ-ᯥᯧ' + 'ᯪ-ᯬᯮ᯲-᯳᯼-᯿ᰀ-ᰣᰤ-ᰫ' + 'ᰴ-ᰵ᰻-᰿᱀-᱉ᱍ-ᱏ᱐-᱙' + 'ᱚ-ᱷᱸ-ᱽ᱾-᱿᳀-᳇᳓᳡' + 'ᳩ-ᳬᳮ-ᳱᳲ-ᳳᳵ-ᳶᴀ-ᴫ' + 'ᴬ-ᵪᵫ-ᵷᵸᵹ-ᶚᶛ-ᶿḀ-ἕ' + 'Ἐ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝ' + 'Ὗ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌ' + 'ῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼ' + 'ⁱⁿₐ-ₜℂℇℊ-ℓℕℙ-ℝ' + 'ℤΩℨK-ℭℯ-ℴℵ-ℸℹ' + 'ℼ-ℿⅅ-ⅉⅎ⅏Ⅰ-ↂↃ-ↄ' + 'ↅ-ↈ⌶-⍺⎕⒜-ⓩ⚬⠀-⣿' + 'Ⰰ-Ⱞⰰ-ⱞⱠ-ⱻⱼ-ⱽⱾ-ⳤ' + 'Ⳬ-ⳮⳲ-ⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯ' + '⵰ⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾ' + 'ⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々〆〇' + '〡-〩〮-〯〱-〵〸-〺〻〼' + 'ぁ-ゖゝ-ゞゟァ-ヺー-ヾヿ' + 'ㄅ-ㄭㄱ-ㆎ㆐-㆑㆒-㆕㆖-㆟' + 'ㆠ-ㆺㇰ-ㇿ㈀-㈜㈠-㈩㈪-㉇' + '㉈-㉏㉠-㉻㉿㊀-㊉㊊-㊰㋀-㋋' + '㋐-㋾㌀-㍶㍻-㏝㏠-㏾㐀-䶵' + '一-鿌ꀀ-ꀔꀕꀖ-ꒌꓐ-ꓷꓸ-ꓽ' + '꓾-꓿ꔀ-ꘋꘌꘐ-ꘟ꘠-꘩ꘪ-ꘫ' + 'Ꙁ-ꙭꙮꚀ-ꚛꚜ-ꚝꚠ-ꛥꛦ-ꛯ' + '꛲-꛷Ꜣ-ꝯꝰꝱ-ꞇ꞉-꞊Ꞌ-ꞎ' + 'Ꞑ-ꞭꞰ-Ʇꟷꟸ-ꟹꟺꟻ-ꠁ' + 'ꠃ-ꠅꠇ-ꠊꠌ-ꠢꠣ-ꠤꠧ꠰-꠵' + '꠶-꠷ꡀ-ꡳꢀ-ꢁꢂ-ꢳꢴ-ꣃ' + '꣎-꣏꣐-꣙ꣲ-ꣷ꣸-꣺ꣻ꤀-꤉' + 'ꤊ-ꤥ꤮-꤯ꤰ-ꥆꥒ-꥓꥟ꥠ-ꥼ' + 'ꦃꦄ-ꦲꦴ-ꦵꦺ-ꦻꦽ-꧀꧁-꧍' + 'ꧏ꧐-꧙꧞-꧟ꧠ-ꧤꧦꧧ-ꧯ' + '꧰-꧹ꧺ-ꧾꨀ-ꨨꨯ-ꨰꨳ-ꨴ' + 'ꩀ-ꩂꩄ-ꩋꩍ꩐-꩙꩜-꩟ꩠ-ꩯ' + 'ꩰꩱ-ꩶ꩷-꩹ꩺꩻꩽꩾ-ꪯꪱ' + 'ꪵ-ꪶꪹ-ꪽꫀꫂꫛ-ꫜꫝ꫞-꫟' + 'ꫠ-ꫪꫫꫮ-ꫯ꫰-꫱ꫲꫳ-ꫴꫵ' + 'ꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮ' + 'ꬰ-ꭚ꭛ꭜ-ꭟꭤ-ꭥꯀ-ꯢꯣ-ꯤ' + 'ꯦ-ꯧꯩ-ꯪ꯫꯬꯰-꯹가-힣' + 'ힰ-ퟆퟋ-ퟻ-豈-舘並-龎' + 'ff-stﬓ-ﬗA-Za-zヲ-ッー' + 'ア-ン゙-゚ᅠ-하-ᅦᅧ-ᅬ' + 'ᅭ-ᅲᅳ-ᅵ',
R: '־׀׃׆-א-ת-ׯ' + 'װ-ײ׳-״-߀-߉ߊ-ߪ' + 'ߴ-ߵߺ-߿ࠀ-ࠕࠚࠤࠨ' + '-࠰-࠾ࡀ-ࡘ-࡞' + '-࢟יִײַ-ﬨשׁ-זּטּ-לּ' + 'מּנּ-סּףּ-פּצּ-ﭏ',
AL: '؈؋؍؛؝؞-؟ؠ-ؿـ' + 'ف-ي٭ٮ-ٯٱ-ۓ۔ەۥ-ۦ' + 'ۮ-ۯۺ-ۼ۽-۾ۿ܀-܍' + 'ܐܒ-ܯ-ݍ-ޥޱ-' + 'ࢠ-ࢲࢳ-ࣣﭐ-ﮱ﮲-﯁﯂-' + 'ﯓ-ﴽ﵀-﵏ﵐ-ﶏ-ﶒ-ﷇ' + '-﷏ﷰ-ﷻ﷼﷾-﷿ﹰ-ﹴ' + 'ﹶ-ﻼ-'
};
var REGEX_STRONG = new RegExp('[' + RANGE_BY_BIDI_TYPE.L + RANGE_BY_BIDI_TYPE.R + RANGE_BY_BIDI_TYPE.AL + ']');
var REGEX_RTL = new RegExp('[' + RANGE_BY_BIDI_TYPE.R + RANGE_BY_BIDI_TYPE.AL + ']');
/**
* Returns the first strong character (has Bidi_Class value of L, R, or AL).
*
* @param str A text block; e.g. paragraph, table cell, tag
* @return A character with strong bidi direction, or null if not found
*/
function firstStrongChar(str) {
var match = REGEX_STRONG.exec(str);
return match == null ? null : match[0];
}
/**
* Returns the direction of a block of text, based on the direction of its
* first strong character (has Bidi_Class value of L, R, or AL).
*
* @param str A text block; e.g. paragraph, table cell, tag
* @return The resolved direction
*/
function firstStrongCharDir(str) {
var strongChar = firstStrongChar(str);
if (strongChar == null) {
return UnicodeBidiDirection.NEUTRAL;
}
return REGEX_RTL.exec(strongChar) ? UnicodeBidiDirection.RTL : UnicodeBidiDirection.LTR;
}
/**
* Returns the direction of a block of text, based on the direction of its
* first strong character (has Bidi_Class value of L, R, or AL), or a fallback
* direction, if no strong character is found.
*
* This function is supposed to be used in respect to Higher-Level Protocol
* rule HL1. (http://www.unicode.org/reports/tr9/#HL1)
*
* @param str A text block; e.g. paragraph, table cell, tag
* @param fallback Fallback direction, used if no strong direction detected
* for the block (default = NEUTRAL)
* @return The resolved direction
*/
function resolveBlockDir(str, fallback) {
fallback = fallback || UnicodeBidiDirection.NEUTRAL;
if (!str.length) {
return fallback;
}
var blockDir = firstStrongCharDir(str);
return blockDir === UnicodeBidiDirection.NEUTRAL ? fallback : blockDir;
}
/**
* Returns the direction of a block of text, based on the direction of its
* first strong character (has Bidi_Class value of L, R, or AL), or a fallback
* direction, if no strong character is found.
*
* NOTE: This function is similar to resolveBlockDir(), but uses the global
* direction as the fallback, so it *always* returns a Strong direction,
* making it useful for integration in places that you need to make the final
* decision, like setting some CSS class.
*
* This function is supposed to be used in respect to Higher-Level Protocol
* rule HL1. (http://www.unicode.org/reports/tr9/#HL1)
*
* @param str A text block; e.g. paragraph, table cell
* @param strongFallback Fallback direction, used if no strong direction
* detected for the block (default = global direction)
* @return The resolved Strong direction
*/
function getDirection(str, strongFallback) {
if (!strongFallback) {
strongFallback = UnicodeBidiDirection.getGlobalDir();
}
!UnicodeBidiDirection.isStrong(strongFallback) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Fallback direction must be a strong direction') : invariant(false) : void 0;
return resolveBlockDir(str, strongFallback);
}
/**
* Returns true if getDirection(arguments...) returns LTR.
*
* @param str A text block; e.g. paragraph, table cell
* @param strongFallback Fallback direction, used if no strong direction
* detected for the block (default = global direction)
* @return True if the resolved direction is LTR
*/
function isDirectionLTR(str, strongFallback) {
return getDirection(str, strongFallback) === UnicodeBidiDirection.LTR;
}
/**
* Returns true if getDirection(arguments...) returns RTL.
*
* @param str A text block; e.g. paragraph, table cell
* @param strongFallback Fallback direction, used if no strong direction
* detected for the block (default = global direction)
* @return True if the resolved direction is RTL
*/
function isDirectionRTL(str, strongFallback) {
return getDirection(str, strongFallback) === UnicodeBidiDirection.RTL;
}
var UnicodeBidi = {
firstStrongChar: firstStrongChar,
firstStrongCharDir: firstStrongCharDir,
resolveBlockDir: resolveBlockDir,
getDirection: getDirection,
isDirectionLTR: isDirectionLTR,
isDirectionRTL: isDirectionRTL
};
module.exports = UnicodeBidi;