This repository has been archived by the owner on Jun 26, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP: A rough PoC of the text direction detection based on the first s…
…trong Unicode character.
- Loading branch information
Showing
4 changed files
with
229 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/** | ||
* @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. | ||
* For licensing, see LICENSE.md. | ||
*/ | ||
|
||
/** | ||
* @module typing/bidi | ||
*/ | ||
|
||
import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; | ||
import { getTextDirection } from './utils/bidi'; | ||
import '../theme/bidi.css'; | ||
|
||
const RTL_CLASS = 'ck-bidi_rtl'; | ||
const LTR_CLASS = 'ck-bidi_ltr'; | ||
|
||
/** | ||
* TODO | ||
* | ||
* @extends module:core/plugin~Plugin | ||
*/ | ||
export default class BiDi extends Plugin { | ||
/** | ||
* @inheritDoc | ||
*/ | ||
static get pluginName() { | ||
return 'BiDi'; | ||
} | ||
|
||
init() { | ||
const editor = this.editor; | ||
const view = editor.editing.view; | ||
const model = editor.model; | ||
const modelDocument = model.document; | ||
const viewDocument = view.document; | ||
const modelSelection = modelDocument.selection; | ||
|
||
this.listenTo( modelDocument, 'change', () => { | ||
view.change( writer => { | ||
const elements = [ ...model.createRangeIn( modelDocument.getRoot() ).getItems() ] | ||
.filter( item => item.is( 'element' ) ); | ||
|
||
elements.forEach( element => { | ||
const elementTextDirection = getModelElementTextDirection( model, element ); | ||
const viewElement = editor.editing.mapper.toViewElement( element ); | ||
|
||
setViewElementTextDirection( writer, viewElement, elementTextDirection ); | ||
} ); | ||
} ); | ||
}, { priority: 'low' } ); | ||
|
||
let lastTextDirection; | ||
|
||
// Save the text direction of the element the user is "entering from". | ||
this.listenTo( viewDocument, 'enter', () => { | ||
const modelElement = modelSelection.getFirstPosition().parent; | ||
lastTextDirection = getModelElementTextDirection( model, modelElement ); | ||
} ); | ||
|
||
// Update the text direction of the element the user "entered to". | ||
this.listenTo( viewDocument, 'enter', () => { | ||
const modelElement = modelSelection.getFirstPosition().parent; | ||
const viewElement = editor.editing.mapper.toViewElement( modelElement ); | ||
|
||
view.change( writer => { | ||
setViewElementTextDirection( writer, viewElement, lastTextDirection ); | ||
} ); | ||
}, { priority: 'low' } ); | ||
} | ||
} | ||
|
||
function getModelElementTextDirection( model, element ) { | ||
const elementRange = model.createRangeIn( element ); | ||
const elementText = [ ...elementRange.getItems() ].map( item => item.data ).join( '' ); | ||
|
||
return getTextDirection( elementText ); | ||
} | ||
|
||
function setViewElementTextDirection( writer, element, direction ) { | ||
if ( direction === 'rtl' ) { | ||
writer.addClass( RTL_CLASS, element ); | ||
writer.removeClass( LTR_CLASS, element ); | ||
} else if ( direction == 'ltr' ) { | ||
writer.addClass( LTR_CLASS, element ); | ||
writer.removeClass( RTL_CLASS, element ); | ||
} else { | ||
writer.removeClass( LTR_CLASS, element ); | ||
writer.removeClass( RTL_CLASS, element ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
/** | ||
* @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. | ||
* For licensing, see LICENSE.md. | ||
*/ | ||
|
||
/** | ||
* @module typing/utils/bidi | ||
*/ | ||
|
||
/* | ||
* As per http://www.unicode.org/Public/8.0.0/ucd/extracted/DerivedBidiClass.txt | ||
* and http://www.unicode.org/reports/tr9/. | ||
*/ | ||
|
||
const BIDI_CLASS_LTR = | ||
'\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u01BA\u01BB\u01BC-\u01BF' + | ||
'\u01C0-\u01C3\u01C4-\u0293\u0294\u0295-\u02AF\u02B0-\u02B8\u02BB-\u02C1\u02D0-\u02D1\u02E0-\u02E4\u02EE' + | ||
'\u0370-\u0373\u0376-\u0377\u037A\u037B-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5' + | ||
'\u03F7-\u0481\u0482\u048A-\u052F\u0531-\u0556\u0559\u055A-\u055F\u0561-\u0587\u0589\u0903\u0904-\u0939' + | ||
'\u093B\u093D\u093E-\u0940\u0949-\u094C\u094E-\u094F\u0950\u0958-\u0961\u0964-\u0965\u0966-\u096F\u0970' + | ||
'\u0971\u0972-\u0980\u0982-\u0983\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9' + | ||
'\u09BD\u09BE-\u09C0\u09C7-\u09C8\u09CB-\u09CC\u09CE\u09D7\u09DC-\u09DD\u09DF-\u09E1\u09E6-\u09EF' + | ||
'\u09F0-\u09F1\u09F4-\u09F9\u09FA\u0A03\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33' + | ||
'\u0A35-\u0A36\u0A38-\u0A39\u0A3E-\u0A40\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A83\u0A85-\u0A8D' + | ||
'\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD\u0ABE-\u0AC0\u0AC9\u0ACB-\u0ACC' + | ||
'\u0AD0\u0AE0-\u0AE1\u0AE6-\u0AEF\u0AF0\u0AF9\u0B02-\u0B03\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28' + | ||
'\u0B2A-\u0B30\u0B32-\u0B33\u0B35-\u0B39\u0B3D\u0B3E\u0B40\u0B47-\u0B48\u0B4B-\u0B4C\u0B57\u0B5C-\u0B5D' + | ||
'\u0B5F-\u0B61\u0B66-\u0B6F\u0B70\u0B71\u0B72-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95' + | ||
'\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BBF\u0BC1-\u0BC2' + | ||
'\u0BC6-\u0BC8\u0BCA-\u0BCC\u0BD0\u0BD7\u0BE6-\u0BEF\u0BF0-\u0BF2\u0C01-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10' + | ||
'\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C41-\u0C44\u0C58-\u0C5A\u0C60-\u0C61\u0C66-\u0C6F\u0C7F\u0C82-\u0C83' + | ||
'\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CBE\u0CBF\u0CC0-\u0CC4\u0CC6' + | ||
'\u0CC7-\u0CC8\u0CCA-\u0CCB\u0CD5-\u0CD6\u0CDE\u0CE0-\u0CE1\u0CE6-\u0CEF\u0CF1-\u0CF2\u0D02-\u0D03' + | ||
'\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D3E-\u0D40\u0D46-\u0D48\u0D4A-\u0D4C\u0D4E\u0D57' + | ||
'\u0D5F-\u0D61\u0D66-\u0D6F\u0D70-\u0D75\u0D79\u0D7A-\u0D7F\u0D82-\u0D83\u0D85-\u0D96\u0D9A-\u0DB1' + | ||
'\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCF-\u0DD1\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2-\u0DF3\u0DF4\u0E01-\u0E30' + | ||
'\u0E32-\u0E33\u0E40-\u0E45\u0E46\u0E4F\u0E50-\u0E59\u0E5A-\u0E5B\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A' + | ||
'\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EB0\u0EB2-\u0EB3\u0EBD' + | ||
'\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F01-\u0F03\u0F04-\u0F12\u0F13\u0F14\u0F15-\u0F17' + | ||
'\u0F1A-\u0F1F\u0F20-\u0F29\u0F2A-\u0F33\u0F34\u0F36\u0F38\u0F3E-\u0F3F\u0F40-\u0F47\u0F49-\u0F6C\u0F7F' + | ||
'\u0F85\u0F88-\u0F8C\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE-\u0FCF\u0FD0-\u0FD4\u0FD5-\u0FD8\u0FD9-\u0FDA' + | ||
'\u1000-\u102A\u102B-\u102C\u1031\u1038\u103B-\u103C\u103F\u1040-\u1049\u104A-\u104F\u1050-\u1055' + | ||
'\u1056-\u1057\u105A-\u105D\u1061\u1062-\u1064\u1065-\u1066\u1067-\u106D\u106E-\u1070\u1075-\u1081' + | ||
'\u1083-\u1084\u1087-\u108C\u108E\u108F\u1090-\u1099\u109A-\u109C\u109E-\u109F\u10A0-\u10C5\u10C7\u10CD' + | ||
'\u10D0-\u10FA\u10FB\u10FC\u10FD-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288' + | ||
'\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310' + | ||
'\u1312-\u1315\u1318-\u135A\u1360-\u1368\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C' + | ||
'\u166D-\u166E\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EB-\u16ED\u16EE-\u16F0\u16F1-\u16F8\u1700-\u170C' + | ||
'\u170E-\u1711\u1720-\u1731\u1735-\u1736\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17B6' + | ||
'\u17BE-\u17C5\u17C7-\u17C8\u17D4-\u17D6\u17D7\u17D8-\u17DA\u17DC\u17E0-\u17E9\u1810-\u1819\u1820-\u1842' + | ||
'\u1843\u1844-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1923-\u1926\u1929-\u192B\u1930-\u1931' + | ||
'\u1933-\u1938\u1946-\u194F\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u19DA' + | ||
'\u1A00-\u1A16\u1A19-\u1A1A\u1A1E-\u1A1F\u1A20-\u1A54\u1A55\u1A57\u1A61\u1A63-\u1A64\u1A6D-\u1A72' + | ||
'\u1A80-\u1A89\u1A90-\u1A99\u1AA0-\u1AA6\u1AA7\u1AA8-\u1AAD\u1B04\u1B05-\u1B33\u1B35\u1B3B\u1B3D-\u1B41' + | ||
'\u1B43-\u1B44\u1B45-\u1B4B\u1B50-\u1B59\u1B5A-\u1B60\u1B61-\u1B6A\u1B74-\u1B7C\u1B82\u1B83-\u1BA0\u1BA1' + | ||
'\u1BA6-\u1BA7\u1BAA\u1BAE-\u1BAF\u1BB0-\u1BB9\u1BBA-\u1BE5\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2-\u1BF3' + | ||
'\u1BFC-\u1BFF\u1C00-\u1C23\u1C24-\u1C2B\u1C34-\u1C35\u1C3B-\u1C3F\u1C40-\u1C49\u1C4D-\u1C4F\u1C50-\u1C59' + | ||
'\u1C5A-\u1C77\u1C78-\u1C7D\u1C7E-\u1C7F\u1CC0-\u1CC7\u1CD3\u1CE1\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF2-\u1CF3' + | ||
'\u1CF5-\u1CF6\u1D00-\u1D2B\u1D2C-\u1D6A\u1D6B-\u1D77\u1D78\u1D79-\u1D9A\u1D9B-\u1DBF\u1E00-\u1F15' + | ||
'\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4' + | ||
'\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4' + | ||
'\u1FF6-\u1FFC\u200E\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126' + | ||
'\u2128\u212A-\u212D\u212F-\u2134\u2135-\u2138\u2139\u213C-\u213F\u2145-\u2149\u214E\u214F\u2160-\u2182' + | ||
'\u2183-\u2184\u2185-\u2188\u2336-\u237A\u2395\u249C-\u24E9\u26AC\u2800-\u28FF\u2C00-\u2C2E\u2C30-\u2C5E' + | ||
'\u2C60-\u2C7B\u2C7C-\u2C7D\u2C7E-\u2CE4\u2CEB-\u2CEE\u2CF2-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F' + | ||
'\u2D70\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6' + | ||
'\u2DD8-\u2DDE\u3005\u3006\u3007\u3021-\u3029\u302E-\u302F\u3031-\u3035\u3038-\u303A\u303B\u303C\u3041-\u3096' + | ||
'\u309D-\u309E\u309F\u30A1-\u30FA\u30FC-\u30FE\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u3191\u3192-\u3195' + | ||
'\u3196-\u319F\u31A0-\u31BA\u31F0-\u31FF\u3200-\u321C\u3220-\u3229\u322A-\u3247\u3248-\u324F\u3260-\u327B\u327F' + | ||
'\u3280-\u3289\u328A-\u32B0\u32C0-\u32CB\u32D0-\u32FE\u3300-\u3376\u337B-\u33DD\u33E0-\u33FE\u3400-\u4DB5' + | ||
'\u4E00-\u9FD5\uA000-\uA014\uA015\uA016-\uA48C\uA4D0-\uA4F7\uA4F8-\uA4FD\uA4FE-\uA4FF\uA500-\uA60B\uA60C' + | ||
'\uA610-\uA61F\uA620-\uA629\uA62A-\uA62B\uA640-\uA66D\uA66E\uA680-\uA69B\uA69C-\uA69D\uA6A0-\uA6E5\uA6E6-\uA6EF' + | ||
'\uA6F2-\uA6F7\uA722-\uA76F\uA770\uA771-\uA787\uA789-\uA78A\uA78B-\uA78E\uA78F\uA790-\uA7AD\uA7B0-\uA7B7' + | ||
'\uA7F7\uA7F8-\uA7F9\uA7FA\uA7FB-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA823-\uA824\uA827' + | ||
'\uA830-\uA835\uA836-\uA837\uA840-\uA873\uA880-\uA881\uA882-\uA8B3\uA8B4-\uA8C3\uA8CE-\uA8CF\uA8D0-\uA8D9' + | ||
'\uA8F2-\uA8F7\uA8F8-\uA8FA\uA8FB\uA8FC\uA8FD\uA900-\uA909\uA90A-\uA925\uA92E-\uA92F\uA930-\uA946' + | ||
'\uA952-\uA953\uA95F\uA960-\uA97C\uA983\uA984-\uA9B2\uA9B4-\uA9B5\uA9BA-\uA9BB\uA9BD-\uA9C0\uA9C1-\uA9CD' + | ||
'\uA9CF\uA9D0-\uA9D9\uA9DE-\uA9DF\uA9E0-\uA9E4\uA9E6\uA9E7-\uA9EF\uA9F0-\uA9F9\uA9FA-\uA9FE\uAA00-\uAA28' + | ||
'\uAA2F-\uAA30\uAA33-\uAA34\uAA40-\uAA42\uAA44-\uAA4B\uAA4D\uAA50-\uAA59\uAA5C-\uAA5F\uAA60-\uAA6F\uAA70' + | ||
'\uAA71-\uAA76\uAA77-\uAA79\uAA7A\uAA7B\uAA7D\uAA7E-\uAAAF\uAAB1\uAAB5-\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2' + | ||
'\uAADB-\uAADC\uAADD\uAADE-\uAADF\uAAE0-\uAAEA\uAAEB\uAAEE-\uAAEF\uAAF0-\uAAF1\uAAF2\uAAF3-\uAAF4\uAAF5' + | ||
'\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5B\uAB5C-\uAB5F' + | ||
'\uAB60-\uAB65\uAB70-\uABBF\uABC0-\uABE2\uABE3-\uABE4\uABE6-\uABE7\uABE9-\uABEA\uABEB\uABEC\uABF0-\uABF9' + | ||
'\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uE000-\uF8FF\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17' + | ||
'\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFF6F\uFF70\uFF71-\uFF9D\uFF9E-\uFF9F\uFFA0-\uFFBE\uFFC2-\uFFC7' + | ||
'\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC'; | ||
|
||
const BIDI_CLASS_RTL = | ||
'\u0590\u05BE\u05C0\u05C3\u05C6\u05C8-\u05CF\u05D0-\u05EA\u05EB-\u05EF\u05F0-\u05F2\u05F3-\u05F4\u05F5-\u05FF' + | ||
'\u07C0-\u07C9\u07CA-\u07EA\u07F4-\u07F5\u07FA\u07FB-\u07FF\u0800-\u0815\u081A\u0824\u0828\u082E-\u082F\u0830-\u083E' + | ||
'\u083F\u0840-\u0858\u085C-\u085D\u085E\u085F-\u089F\u200F\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB37\uFB38-\uFB3C\uFB3D\uFB3E' + | ||
'\uFB3F\uFB40-\uFB41\uFB42\uFB43-\uFB44\uFB45\uFB46-\uFB4F'; | ||
|
||
const BIDI_CLASS_ARABIC = | ||
'\u0608\u060B\u060D\u061B\u061C\u061D\u061E-\u061F\u0620-\u063F\u0640\u0641-\u064A\u066D\u066E-\u066F' + | ||
'\u0671-\u06D3\u06D4\u06D5\u06E5-\u06E6\u06EE-\u06EF\u06FA-\u06FC\u06FD-\u06FE\u06FF\u0700-\u070D\u070E' + | ||
'\u070F\u0710\u0712-\u072F\u074B-\u074C\u074D-\u07A5\u07B1\u07B2-\u07BF\u08A0-\u08B4\u08B5-\u08E2' + | ||
'\uFB50-\uFBB1\uFBB2-\uFBC1\uFBC2-\uFBD2\uFBD3-\uFD3D\uFD40-\uFD4F\uFD50-\uFD8F\uFD90-\uFD91' + | ||
'\uFD92-\uFDC7\uFDC8-\uFDCF\uFDF0-\uFDFB\uFDFC\uFDFE-\uFDFF\uFE70-\uFE74\uFE75\uFE76-\uFEFC\uFEFD-\uFEFE'; | ||
|
||
const STRONG_REGEXP = new RegExp( `[${ BIDI_CLASS_LTR }${ BIDI_CLASS_RTL }${ BIDI_CLASS_ARABIC }]` ); | ||
const IS_RTL_REGEXP = new RegExp( `[${ BIDI_CLASS_RTL }${ BIDI_CLASS_ARABIC }]` ); | ||
|
||
function getFirstStrongCharacter( string ) { | ||
const match = STRONG_REGEXP.exec( string ); | ||
|
||
if ( match === null ) { | ||
return null; | ||
} else { | ||
return match[ 0 ]; | ||
} | ||
} | ||
|
||
export function getTextDirection( string ) { | ||
const firstStrongChar = getFirstStrongCharacter( string ); | ||
|
||
if ( !firstStrongChar ) { | ||
return null; | ||
} else { | ||
const match = IS_RTL_REGEXP.exec( firstStrongChar ); | ||
|
||
if ( match === null ) { | ||
return 'ltr'; | ||
} else { | ||
return 'rtl'; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/* | ||
* Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. | ||
* For licensing, see LICENSE.md. | ||
*/ | ||
|
||
.ck-bidi_rtl { | ||
direction: rtl; | ||
text-align: right; | ||
} |