Skip to content

sandello/sirius-sync-class

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

24 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

НСкоторыС Π·Π°Π΄Π°Ρ‡ΠΈ синхронзиации

ΠŸΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ Ρ€Π°Π±ΠΎΡ‚Ρ‹

Π’Π°ΠΌ понадобится:

Π‘ΠΊΠ»ΠΎΠ½ΠΈΡ€ΡƒΠΉΡ‚Π΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚. ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π² VS Code. УстановитС quart: pip install -U quart.

ПонСдСльник 16.12

Π¨Π°Π³ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ: ΠΎΠ±ΠΌΠ΅Π½ сообщСниями

ЗапуститС сСрвСр -- python3.7 server1.py -- ΠΈ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ -- http://localhost:5000. ΠŸΠ΅Ρ€Π΅ΠΉΠ΄ΠΈΡ‚Π΅ Π² ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΡƒΡ€ΠΎΠΊ.

Π’ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅ ΠΎΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ "Π˜Π½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ для Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°", Π² Π½ΠΈΡ… Π½Π°ΠΉΠ΄ΠΈΡ‚Π΅ JS-консоль. Π’Π°ΠΌ Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ сообщСниС "Начали Ρ€Π°Π±ΠΎΡ‚Ρƒ!".

ΠžΠ·Π½Π°ΠΊΠΎΠΌΡŒΡ‚Π΅ΡΡŒ с исходных ΠΊΠΎΠ΄ΠΎΠΌ сСрвСрной части server1.py ΠΈ исходных ΠΊΠΎΠ΄ΠΎΠΌ страницы templates/p_1_start.html. Π£Π±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅Ρ‚Π΅, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ связка Π²Π΅Π±-страницы ΠΈ сСрвСра.

Π‘Π΄Π΅Π»Π°ΠΉΡ‚Π΅ ΡƒΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ Π² templates/p_1_start.html.

Π”Π°Π»Π΅Π΅, запуститС Π²Π·Π°ΠΌΠ΅Π½ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ сСрвСра -- Π²Ρ‚ΠΎΡ€ΠΎΠΉ (server2.py). ΠžΠ·Π½Π°ΠΊΠΎΠΌΡŒΡ‚Π΅ΡΡŒ с коммСнтариями Π² исходном ΠΊΠΎΠ΄Π΅. Π˜Π·ΡƒΡ‡ΠΈΡ‚Π΅ отличия Π² ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠΈ ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.

НаконСц, запуститС Π²Π·Π°ΠΌΠ΅Π½ Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ сСрвСра -- Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ (server3.py). ΠžΠ·Π½Π°ΠΊΠΎΠΌΡŒΡ‚Π΅ΡΡŒ с коммСнтариями Π² исходном ΠΊΠΎΠ΄Π΅. Π˜Π·ΡƒΡ‡ΠΈΡ‚Π΅ отличия Π² ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠΈ ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.

Π‘Π΄Π΅Π»Π°ΠΉΡ‚Π΅ ΡƒΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ Π² server3.py.

Π¨Π°Π³ Π²Ρ‚ΠΎΡ€ΠΎΠΉ: ΠΌΠΎΠ½ΠΎΡ‚ΠΎΠ½Π½Ρ‹ΠΉ счСтчик

Π’Π°ΠΆΠ½ΠΎ: Π²Ρ‚ΠΎΡ€ΠΎΠΉ шаг Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½ΠΎΠ³ΠΎ Π² server3.py упраТнСния.

ЗапуститС сСрвСр -- python3.7 server3.py -- ΠΈ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ -- http://localhost:5000. ΠŸΠ΅Ρ€Π΅ΠΉΠ΄ΠΈΡ‚Π΅ Π²ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΡƒΡ€ΠΎΠΊ.

Π Π΅Π°Π»ΠΈΠ·ΡƒΠΉΡ‚Π΅ ΠΌΠΎΠ½ΠΎΡ‚ΠΎΠ½Π½Ρ‹ΠΉ счСтчик: ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ расти. Для этого вспомнитС Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π½Π½ΡƒΡŽ Π½Π° занятии модСль счСтчика. Π‘Π»Π΅Π΄ΡƒΠΉΡ‚Π΅ указаниям Π² templates/p_2_inc_counter.html.

Π¨Π°Π³ Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ: ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ счСтчик

Π­Ρ‚ΠΎ вашС домашнСС Π·Π°Π΄Π°Π½ΠΈΠ΅.

Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, Π΄ΠΎΠ΄Π΅Π»Π°ΠΉΡ‚Π΅ ΠΊΠ»Π°ΡΡΠ½ΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΈ Π΄ΠΎΠ²Π΅Π΄ΠΈΡ‚Π΅ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ счСтчик Π΄ΠΎ Ρ€Π°Π±ΠΎΡ‡Π΅Π³ΠΎ состояния.

Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡ счСтчика.

ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π·Π°Π³ΠΎΡ‚ΠΎΠ²ΠΊΡƒ ΠΈΠ· templates/p_2_inc_counter.html:

  • Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΄Π²Π΅ ΠΊΠ½ΠΎΠΏΠΊΠΈ -- увСличСния ΠΈ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡ счСтчика;
  • Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ тСстовый сцСнарий для наТатия Π΄Π²ΡƒΡ… ΠΊΠ½ΠΎΠΏΠΎΠΊ ΠΏΠΎΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ.

Π’Ρ‚ΠΎΡ€Π½ΠΈΠΊ 17.12

Π’Π°ΠΆΠ½ΠΎ: ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ сСрвСром server4.py, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ содСрТит всю Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½ΡƒΡŽ Ρ€Π°Π½Π΅Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ.

Π¨Π°Π³ Ρ‡Π΅Ρ‚Π²Π΅Ρ€Ρ‚Ρ‹ΠΉ: ΠΏΡ€Π°Π²ΠΊΠΈ ΠΏΠΎ Π›Π΅Π²Π΅Π½ΡˆΡ‚Π΅ΠΉΠ½Ρƒ

Π’Π°ΡˆΠ° Π·Π°Π΄Π°Ρ‡Π° -- Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ расчСта списка ΠΏΡ€Π°Π²ΠΎΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ пСрСводят ΠΎΠ΄Π½Ρƒ строку Π² Π΄Ρ€ΡƒΠ³ΡƒΡŽ. ΠŸΡ€Π°Π²ΠΊΠ° -- это опСрация вставки символа, опСрация удалСния символа ΠΈ опСрация Π·Π°ΠΌΠ΅Π½Ρ‹ символа.

Π§Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ расчСта списка ΠΏΡ€Π°Π²ΠΎΠΊ Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ расчСта расстояниС Π›Π΅Π²Π΅Π½ΡˆΡ‚Π΅ΠΉΠ½Π° ΠΌΠ΅ΠΆΠ΄Ρƒ двумя строками ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² Π½Π΅Π³ΠΎ ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹ΠΉ Ρ…ΠΎΠ΄, ΠΈΠ·Π²Π»Π΅ΠΊΠ°ΡŽΡ‰ΠΈΠΉ ΠΏΡ€Π°Π²ΠΊΠΈ.

Π‘ΠΈΠ³Π½Π°Ρ‚ΡƒΡ€Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ такая:

function editList(left, right);

Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ Π² Ρ„Π°ΠΉΠ»Π΅ templates/j_editlist.js. Π­Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΏΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° шагС 6.

ΠžΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ подробности -- см. Π² templates/p_4_editlist.html.

Π¨Π°Π³ пятый: модСль Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°

NB: Если Π²Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π΅ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ, Π±Π΅Π· Π»Π΅ΠΊΡ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π°, Ρ‚ΠΎ для Π»ΡƒΡ‡ΡˆΠ΅Π³ΠΎ понимания ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ Π²Π°ΠΌ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ ΡΡ‚Π°Ρ‚ΡŒΠΈ ΠΏΠΎ TreeDoc ΠΈ LSEQ.

Π’Π°ΡˆΠ° Π·Π°Π΄Π°Ρ‡Π° -- Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ модСль Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ вставки, удалСния ΠΈ Π·Π°ΠΌΠ΅Π½Ρ‹, Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΡƒΡŽ Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎΠ΅ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ символов Π²Π½ΡƒΡ‚Ρ€ΠΈ. Π’Π°ΠΊΠΆΠ΅ модСль Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π° Π΄ΠΎΠ»ΠΆΠ½Π° ΡΠ΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π² ΠΏΠ°Ρ€Ρƒ мноТСств D1 ΠΈ D2: D1 -- мноТСство ΠΏΠ°Ρ€ (позиция, символ), D2 -- мноТСство ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Ρ… ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΉ.

Π‘ΠΈΠ³Π½Π°Ρ‚ΡƒΡ€Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π° Ρ‚Π°ΠΊΠΈΠ΅:

function public_newDocument() {}
function public_getContent(document) {}

function public_serializeState(document) {} // ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚Π»ΠΎΠΆΠΈΡ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄ΠΎ 7-Π³ΠΎ шага
function public_mergeWithSerializedState(document, serializedState) {} // ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚Π»ΠΎΠΆΠΈΡ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄ΠΎ 7-Π³ΠΎ шага

function public_insertAfter(document, index, symbol) {} // рСализация фиксирована, Π½Π΅ Ρ‚Ρ€ΠΎΠ³Π°Ρ‚ΡŒ
function public_remove(document, index) {} // рСализация фиксирована, Π½Π΅ Ρ‚Ρ€ΠΎΠ³Π°Ρ‚ΡŒ
function public_replace(document, index, symbol) {} // рСализация фиксирована, Π½Π΅ Ρ‚Ρ€ΠΎΠ³Π°Ρ‚ΡŒ

function _getPositionByIndex(document, index) {}
function _allocate(document, begin, end) {}
function _allocateLeft(document, begin, end) {}
function _allocateRight(document, begin, end) {}
function _applyInsert(document, position, symbol) {}
function _applyRemove(document, position) {}

Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ Π² Ρ„Π°ΠΉΠ»Π΅ templates/j_treedoc.js. Π­Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΏΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° шагС 6.

ОписаниС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, указания ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ подробности -- Π² templates/p_5_treedoc.html.

Π§Π΅Ρ‚Π²Π΅Ρ€Π³ 19.12

Π¨Π°Π³ ΡˆΠ΅ΡΡ‚ΠΎΠΉ: ΠΈΠ½Ρ‚Π΅Π³Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ тСкстовоС ΠΏΠΎΠ»Π΅ ΠΈ модСль Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°

Π’Π°ΡˆΠ° Π·Π°Π΄Π°Ρ‡Π° -- ΡΠΎΡΡ‚Ρ‹ΠΊΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ΄ ΠΈΠ· Ρ‡Π΅Ρ‚Π²Π΅Ρ€Ρ‚ΠΎΠ³ΠΎ ΠΈ пятого шагов.

Π’ Π·Π°Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ΅ вас ΠΆΠ΄Π΅Ρ‚ интСрфСйс с тСкстовым ΠΏΠΎΠ»Π΅ΠΌ. ΠŸΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ тСкстового поля Π² Π½ΠΈΠΆΠ½Π΅ΠΉ части экрана с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ editList ΠΈΠ· templates/j_editlist.js пСрСсчитываСтся список ΠΏΡ€Π°Π²ΠΎΠΊ ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ содСрТимым ΠΌΠΎΠ΄Π΅Π»ΠΈ (правая Ρ‡Π°ΡΡ‚ΡŒ экрана) ΠΈ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ содСрТимым тСкстового поля (лСвая Ρ‡Π°ΡΡ‚ΡŒ экрана).

Π’Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π»ΠΎΠ³ΠΈΠΊΡƒ Π·Π° ΠΊΠ½ΠΎΠΏΠΊΠΎΠΉ "ΠŸΠ΅Ρ€Π΅Π½Π΅ΡΡ‚ΠΈ Π² модСль", которая ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ содСрТимоС ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΊ Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅ строкС, Ρ‡Ρ‚ΠΎ ΠΈ Π² тСкстовом ΠΏΠΎΠ»Π΅.

Указания ΠΈ подробности -- см. Π² templates/p_6_textarea.html.

Π¨Π°Π³ сСдьмой: собираСм Π²ΠΎΠ΅Π΄ΠΈΠ½ΠΎ

NB: Если Π²Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π΅ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ, Π±Π΅Π· Π»Π΅ΠΊΡ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π°, Ρ‚ΠΎ для Π»ΡƒΡ‡ΡˆΠ΅Π³ΠΎ понимания ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ Π²Π°ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ»Π΅Π½Π° ΡΡ‚Π°Ρ‚ΡŒΡ CRATE: Writing Stories Together with our Browsers.

Π’Π°ΡˆΠ° Π·Π°Π΄Π°Ρ‡Π° -- Π²Π·ΡΡ‚ΡŒ Π½Π°Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ с ΡˆΠ΅ΡΡ‚ΠΎΠ³ΠΎ шага ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ пСрСсылку Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°.

Π‘Ρ‚Π°Ρ€Ρ‚ΠΎΠ²Ρ‹ΠΉ шаблон ΠΈ указания -- см. templates/p_7_integration.html.

Код Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΡΠ΅Ρ‚ΡŒΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ·Π°ΠΈΠΌΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ· ΠΏΠ΅Ρ€Π²Ρ‹Ρ… Ρ‚Ρ€Π΅Ρ… шагов. Код для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с тСкстовым ΠΏΠΎΠ»Π΅ΠΌ -- ΠΈΠ· ΡˆΠ΅ΡΡ‚ΠΎΠ³ΠΎ.

Π­Ρ‚ΠΎ Π·Π°Π΄Π°Π½ΠΈΠ΅ для ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ.

NB: ΠŸΡ€ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ сообщСния ΠΏΠΎ сСти спСрва всСгда Π½ΡƒΠΆΠ½ΠΎ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ тСкстовоС ΠΏΠΎΠ»Π΅ ΠΈ модСль, ΠΈ лишь Π·Π°Ρ‚Π΅ΠΌ -- ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ измСнСния, ΠΏΡ€ΠΈΡˆΠ΅Π΄ΡˆΠΈΠ΅ ΠΏΠΎ сСти.

ΠŸΡΡ‚Π½ΠΈΡ†Π° 20.12

Π£Π»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΠ΅ 1: Π½Π΅ΠΏΡ€Ρ‹Π³Π°ΡŽΡ‰ΠΈΠΉ курсор

Π§Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ ΠΏΡ€Ρ‹Π³Π°ΡŽΡ‰Π΅Π³ΠΎ курсора ΠΏΡ€ΠΈ синхронизации, Π½ΡƒΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅:

Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, Π² j_treedoc.js Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ:

function _getIndexByPosition(document, position) {
    // Π’Π΅Ρ€Π½ΡƒΡ‚ΡŒ индСкс ΠΏΠΎ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ.
    // Π’ΠΎ Π΅ΡΡ‚ΡŒ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ число Π½Π΅ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Ρ… символов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΡ€Π΅Π΄ΡˆΠ΅ΡΡ‚Π²ΡƒΡŽΡ‚ Π΄Π°Π½Π½ΠΎΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ.
}

ВСсты для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ:

function testPositionSync() {
    let d = public_newDocument();
    public_insertAfter(d, -1, "c");
    public_insertAfter(d,  0, "a");
    public_insertAfter(d,  1, "t");
    assertEquals(public_getContent(d), "cat");
    for (var i = -1; i <= 3; ++i) {
        assertEquals(i, _getIndexByPosition(d, _getPositionByIndex(d, i)));
    }
}

function testPositionSyncWithInsertions() {
    let d = public_newDocument();
    public_insertAfter(d, -1, "a");
    var p = _getPositionByIndex(d, 0);

    assertEquals(public_getContent(d), "a");
    assertEquals(0, _getIndexByPosition(d, p));

    public_insertAfter(d, -1, "b");
    assertEquals(public_getContent(d), "ba");
    assertEquals(1, _getIndexByPosition(d, p));

    public_insertAfter(d, -1, "c");
    assertEquals(public_getContent(d), "cba");
    assertEquals(2, _getIndexByPosition(d, p));
}

function testPositionSyncWithDeletions() {
    let d = public_newDocument();
    public_insertAfter(d, -1, "c");
    public_insertAfter(d,  0, "a");
    public_insertAfter(d,  1, "t");
    var p = _getPositionByIndex(d, 2);

    assertEquals(public_getContent(d), "cat");
    assertEquals(2, _getIndexByPosition(d, p));
    public_remove(d, 0);
    assertEquals(public_getContent(d), "at");
    assertEquals(1, _getIndexByPosition(d, p));
    public_remove(d, 0);
    assertEquals(public_getContent(d), "t");
    assertEquals(0, _getIndexByPosition(d, p));
}

Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡŽ ΠΌΠ΅ΠΆΠ΄Ρƒ тСкстовым ΠΏΠΎΠ»Π΅ΠΌ ΠΈ модСлью.

Π Π°Π±ΠΎΡ‚Π° с курсором строится Ρ‡Π΅Ρ€Π΅Π· Ρ€Π°Π±ΠΎΡ‚Ρƒ с Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ ΠΎΠ±Π»Π°ΡΡ‚ΡŒΡŽ -- selection range. Π­Ρ‚ΠΎ ΠΏΠ°Ρ€Π° чисСл, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰ΠΈΡ… Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ тСкста. Если Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ пустой, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ лСвая ΠΈ правая Π³Ρ€Π°Π½ΠΈΡ†Ρ‹ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‚, Ρ‚ΠΎ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ ΠΊΠΎΠ΄ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚ΠΎΡ‡ΠΊΡƒ располоТСния курсора.

Наша Π·Π°Π΄Π°Ρ‡Π° состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ выдСлСния Π½Π° этапС синхронизации.

Для получСния Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ области ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄:

var start = $("#integration-textarea").prop("selectionStart");
var end = $("#integration-textarea").prop("selectionEnd");
console.log("ΠšΡƒΡ€ΡΠΎΡ€ находится Π² ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ (" + start + ", " + end + ")");

Для обновлСния Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ области ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄:

$("#integration-textarea").get()[0].setSelectionRange(start, end);

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ Π·Π°Π΄Π°Ρ‡Ρƒ сохранСния полоТСния курсора, ΠΊΠΎΠ΄ синхронизации Π½ΡƒΠΆΠ½ΠΎ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Ρ‚Π°ΠΊ:

var startIndex = $("#integration-textarea").prop("selectionStart");
var startPosition = _getPositionByIndex(document, startIndex);
var endIndex = $("#integration-textarea").prop("selectionEnd");
var endPosition = _getPositionByIndex(document, endIndex);

// здСсь ΠΊΠΎΠ΄ синхронизации

startIndex = _getIndexByPosition(startPosition);
endIndex = _getIndexByPosition(endPosition);

$("#integration-textarea").get()[0].setSelectionRange(startIndex, endIndex);

Π£Π»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΠ΅ 2: ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ editList

Π’ editList ΠΏΡ€ΠΈ расчСтС списка ΠΏΡ€Π°Π²ΠΎΠΊ ΠΌΡ‹ ΠΈΡ‰Π΅ΠΌ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎ Π΄Π»ΠΈΠ½Π΅ список ΠΏΡ€Π°Π²ΠΎΠΊ. Π‘Π°ΠΌΠΎ свойство ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΌΡ‹ Π½ΠΈΠΊΠ°ΠΊ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ. Π’Π°ΠΊΠΆΠ΅ строки, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Π΅ ΠΊΠ°ΠΊ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ editList ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ Π² нСбольшой : ΠΌΡ‹ отслСТиваСм ΠΏΡ€Π°Π²ΠΊΠΈ, внСсСнныС Ρ‡Π΅Π»ΠΎΠ²Π΅ΠΊΠΎΠΌ, ΠΈ чСловСчСскиС ΠΏΡ€Π°Π²ΠΊΠΈ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅.

ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ прСдлагаСтся Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ editList(left, right) ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ эвристику: откусим Ρƒ left ΠΈ right ΠΎΠ±Ρ‰ΠΈΠΉ прСфикс, Π΄Π°Π»Π΅Π΅ откусим Ρƒ left ΠΈ right ΠΎΠ±Ρ‰ΠΈΠΉ суффикс, ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послС этого -- для Π΄Π²ΡƒΡ… ΠΎΡΡ‚Π°Π²ΡˆΠΈΡ…ΡΡ сСрСдин строк -- посчитаСм editList (Π½Π΅ Π·Π°Π±Ρ‹Π² ΡΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ индСксы).

** 1: Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹Π΅ строки

left  = "hello, dolly"
right = "hello dolly"

** 2: ΠžΡ‚ΠΊΡƒΡΡ‹Π²Π°Π΅ΠΌ прСфикс

p     = "hello"
left  = ", dolly"
right = " dolly"

** 3: ΠžΡ‚ΠΊΡƒΡΡ‹Π²Π°Π΅ΠΌ суффикс

p     = "hello"
s     = " dolly"
left  = ","
right = ""

Π”Π°Π»Π΅Π΅ считаСм editList(left, right); индСксы ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π° Π΄Π»ΠΈΠ½Ρƒ ΠΎΠ±Ρ‰Π΅Π³ΠΎ прСфикса.

Как ΠΈΠ·ΠΌΠ΅Ρ€ΠΈΡ‚ΡŒ Π²Ρ‹Π³ΠΎΠ΄Ρƒ ΠΎΡ‚ Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡ?

Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Π² ΠΊΠΎΠ΄ страницы ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ для измСрСния Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ:

function bench(name, fn) {
    var begin = new Date();
    var result = fn();
    var end = new Date();
    console.log("[bench] Π€Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ " + name + " выполнялся " + (end - begin) + "мс");
    return result;
}

// Π”Π°Π»Π΅Π΅ ΠΏΠΎ ΠΊΠΎΠ΄Ρƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.
// Π‘ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ языковоС сокращСниС:
//
//   () => expr;
//
// Π­ΠΊΠ²ΠΈΠ²Π°Π»Π΅Π½Ρ‚Π½ΠΎ:
//
//   function() { return expr; }
//
// Π’ΠΎΠ³Π΄Π°:

// Π‘Ρ‹Π»ΠΎ:
var diff = editList(left, right);
// Π‘Ρ‚Π°Π»ΠΎ:
var diff = bench("editList-1", () => editList(left, right));

// Π‘Ρ‹Π»ΠΎ:
$(...).val(public_getContent(d));

// Π‘Ρ‚Π°Π»ΠΎ Ρ‚Π°ΠΊ:
bench("render", () => $(...).val(public_getContent(d)));
// Или Ρ‚Π°ΠΊ:
$(...).val(bench("render", () => public_getContent(d)));

Π£Π»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΠ΅ 3: ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅ΠΌ объСм синхронизации

БСйчас ΠΏΡ€ΠΈ ΠΎΠ±Ρ‰Π΅Π½ΠΈΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌΠΈ ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ ΠΏΠΎΠ»Π½ΠΎΠ΅ состояниС Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ сущСствСнным объСмом для Π±ΠΎΠ»ΡŒΡˆΠΈΡ… Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ².

ΠŸΡ€ΠΈ этом модСль Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π° -- с мноТСствами D1 ΠΈ D2 -- ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π² мноТСства D1 ΠΈ D2 элСмСнты Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ΡΡ.

Π—Π° счСт этого наблюдСния ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡΠΊΠΎΠ½ΠΎΠΌΠΈΡ‚ΡŒ Π½Π° объСмС ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ ΠΏΠ΅Ρ€Π΅ΡΡ‹Π»Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½ΠΎΠ²Ρ‹Π΅ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π½Ρ‹Π΅ элСмСнты Π² D1 ΠΈ D2.

Π£Π»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΠ΅ 4: ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅ΠΌ частоту синхронизации

БСйчас ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΌΠ΅ΠΆΠ΄Ρƒ тСкстовым ΠΏΠΎΠ»Π΅ΠΌ, модСлью ΠΈ сСрвСром ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ тСкстового поля.

МоТно Ρ‡ΡƒΡ‚ΡŒ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ частоту синхронизации, дСлая Π΅Ρ‘ Π½Π΅ Ρ‡Π°Ρ‰Π΅, Ρ‡Π΅ΠΌ Ρ€Π°Π· Π² нСсколько миллисСкунд.

Для этого ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ throttle ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ lodash.

Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ: скачайтС ΠΈΠ· рСпозитория Ρ„Π°ΠΉΠ» static/js/lodash.min.js, Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Π² p_7_integration.html строку <script src="/static/js/lodash.min.js" crossorigin="anonymous"></script> рядом с Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΎ jquery, popper.

Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, трансформируйтС ваш ΠΊΠΎΠ΄ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

// Π‘Ρ‹Π»ΠΎ:

$("#integration-textarea").on("input", function() {
    // ... Ρ€Π°Π·-Π΄Π²Π°-Ρ‚Ρ€ΠΈ ...
});

// Π‘Ρ‚Π°Π»ΠΎ:

var onInput = _.throttle(function() {
    // ... Ρ€Π°Π·-Π΄Π²Π°-Ρ‚Ρ€ΠΈ ...
}, /* Π’Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Π½Π΅ Ρ‡Π°Ρ‰Π΅, Ρ‡Π΅ΠΌ ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ */ 100 /* миллисСкунд. */);

$("#integration-textarea").on("input", onInput);
$("#integration-textarea").on("blur", onInput.flush);

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published