8
0
Просмотр исходного кода

Merge pull request #54 from ckeditor/t/53

Added: unicode utils.
Piotr Jasiun 9 лет назад
Родитель
Сommit
23662e25c6
2 измененных файлов с 140 добавлено и 0 удалено
  1. 55 0
      packages/ckeditor5-utils/src/unicode.js
  2. 85 0
      packages/ckeditor5-utils/tests/unicode.js

+ 55 - 0
packages/ckeditor5-utils/src/unicode.js

@@ -0,0 +1,55 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * Set of utils to handle unicode characters.
+ *
+ * @namespace utils.unicode
+ */
+
+/**
+ * Checks whether given `character` is a combining mark.
+ *
+ * @param {String} character Character to check.
+ * @returns {Boolean}
+ */
+export function isCombiningMark( character ) {
+	return !!character && character.length == 1 && /[\u0300-\u036f\u1ab0-\u1aff\u1dc0-\u1dff\u20d0-\u20ff\ufe20-\ufe2f]/.test( character );
+}
+
+/**
+ * Checks whether given `character` is a half of surrogate pair.
+ *
+ * @param {String} character Character to check.
+ * @returns {Boolean}
+ */
+export function isSurrogateHalf( character ) {
+	return !!character && character.length == 1 && /[\ud800-\udfff]/.test( character );
+}
+
+/**
+ * Checks whether given offset in a string is inside a surrogate pair (between two surrogate halves).
+ *
+ * @param {String} string String to check.
+ * @param {Number} offset Offset to check.
+ * @returns {Boolean}
+ */
+export function isInsideSurrogatePair( string, offset ) {
+	const charAfter = string.charAt( offset );
+	const charBefore = string.charAt( offset - 1 );
+
+	return isSurrogateHalf( charAfter ) && isSurrogateHalf( charBefore );
+}
+
+/**
+ * Checks whether given offset in a string is between base character and combining mark or between two combining marks.
+ *
+ * @param {String} string String to check.
+ * @param {Number} offset Offset to check.
+ * @returns {Boolean}
+ */
+export function isInsideCombinedSymbol( string, offset ) {
+	return isCombiningMark( string.charAt( offset ) );
+}

+ 85 - 0
packages/ckeditor5-utils/tests/unicode.js

@@ -0,0 +1,85 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+import { isSurrogateHalf, isCombiningMark, isInsideSurrogatePair, isInsideCombinedSymbol } from '/ckeditor5/utils/unicode.js';
+
+describe( 'utils', () => {
+	describe( 'unicode', () => {
+		describe( 'isSurrogateHalf', () => {
+			it( 'should return true if given character is a surrogate half', () => {
+				// Half of pile of poo.
+				expect( isSurrogateHalf( '\uD83D' ) ).to.be.true;
+			} );
+
+			it( 'should return false if given character is not a surrogate half', () => {
+				expect( isSurrogateHalf( 'a' ) ).to.be.false;
+				expect( isSurrogateHalf( '𨭎' ) ).to.be.false;
+			} );
+
+			it( 'should return false for falsy values', () => {
+				expect( isSurrogateHalf( null ) ).to.be.false;
+				expect( isSurrogateHalf( undefined ) ).to.be.false;
+				expect( isSurrogateHalf( false ) ).to.be.false;
+				expect( isSurrogateHalf( 0 ) ).to.be.false;
+			} );
+		} );
+
+		describe( 'isCombiningMark', () => {
+			it( 'should return true if given character is a combining mark', () => {
+				expect( isCombiningMark( '̣' ) ).to.be.true;
+			} );
+
+			it( 'should return false if given character is not a combining mark', () => {
+				expect( isCombiningMark( 'a' ) ).to.be.false;
+				expect( isCombiningMark( 'q̣' ) ).to.be.false;
+			} );
+
+			it( 'should return false for falsy values', () => {
+				expect( isCombiningMark( null ) ).to.be.false;
+				expect( isCombiningMark( undefined ) ).to.be.false;
+				expect( isCombiningMark( false ) ).to.be.false;
+				expect( isCombiningMark( 0 ) ).to.be.false;
+			} );
+		} );
+
+		describe( 'isInsideSurrogatePair', () => {
+			const testString = 'a𨭎b';
+
+			it( 'should return true if given offset in a string is inside a surrogate pair', () => {
+				expect( isInsideSurrogatePair( testString, 2 ) ).to.be.true;
+			} );
+
+			it( 'should return false if given offset in a string is not inside a surrogate pair', () => {
+				expect( isInsideSurrogatePair( testString, 1 ) ).to.be.false;
+				expect( isInsideSurrogatePair( testString, 3 ) ).to.be.false;
+			} );
+
+			it( 'should return false if given offset in a string is at the string beginning or end', () => {
+				expect( isInsideSurrogatePair( testString, 0 ) ).to.be.false;
+				expect( isInsideSurrogatePair( testString, 4 ) ).to.be.false;
+			} );
+		} );
+
+		describe( 'isInsideCombinedSymbol', () => {
+			const testString = 'aa̻̐ͩbb';
+
+			it( 'should return true if given offset in a string is inside a symbol with combining mark', () => {
+				expect( isInsideCombinedSymbol( testString, 2 ) ).to.be.true;
+				expect( isInsideCombinedSymbol( testString, 3 ) ).to.be.true;
+				expect( isInsideCombinedSymbol( testString, 4 ) ).to.be.true;
+			} );
+
+			it( 'should return false if given offset in a string is not inside a symbol with combining mark', () => {
+				expect( isInsideCombinedSymbol( testString, 1 ) ).to.be.false;
+				expect( isInsideCombinedSymbol( testString, 5 ) ).to.be.false;
+			} );
+
+			it( 'should return false if given offset in a string is at the string beginning or end', () => {
+				expect( isInsideCombinedSymbol( testString, 0 ) ).to.be.false;
+				expect( isInsideCombinedSymbol( testString, 6 ) ).to.be.false;
+			} );
+		} );
+	} );
+} );