Browse Source

Fix some entities

Small refactor of RichTextProcessor
master
morethanwords 4 years ago
parent
commit
ee4d05c9e5
  1. 84
      src/layer.d.ts
  2. 2
      src/lib/appManagers/appDialogsManager.ts
  3. 2
      src/lib/appManagers/appMessagesManager.ts
  4. 353
      src/lib/richtextprocessor.ts
  5. 9
      src/lib/services.ts
  6. 7
      src/scripts/generate_mtproto_types.js
  7. 120
      src/scripts/in/schema_additional_params.json

84
src/layer.d.ts vendored

@ -3795,125 +3795,166 @@ export namespace ReplyMarkup { @@ -3795,125 +3795,166 @@ export namespace ReplyMarkup {
/**
* @link https://core.telegram.org/type/MessageEntity
*/
export type MessageEntity = MessageEntity.messageEntityUnknown | MessageEntity.messageEntityMention | MessageEntity.messageEntityHashtag | MessageEntity.messageEntityBotCommand | MessageEntity.messageEntityUrl | MessageEntity.messageEntityEmail | MessageEntity.messageEntityBold | MessageEntity.messageEntityItalic | MessageEntity.messageEntityCode | MessageEntity.messageEntityPre | MessageEntity.messageEntityTextUrl | MessageEntity.messageEntityMentionName | MessageEntity.inputMessageEntityMentionName | MessageEntity.messageEntityPhone | MessageEntity.messageEntityCashtag | MessageEntity.messageEntityUnderline | MessageEntity.messageEntityStrike | MessageEntity.messageEntityBlockquote | MessageEntity.messageEntityBankCard;
export type MessageEntity = MessageEntity.messageEntityUnknown | MessageEntity.messageEntityMention | MessageEntity.messageEntityHashtag | MessageEntity.messageEntityBotCommand | MessageEntity.messageEntityUrl | MessageEntity.messageEntityEmail | MessageEntity.messageEntityBold | MessageEntity.messageEntityItalic | MessageEntity.messageEntityCode | MessageEntity.messageEntityPre | MessageEntity.messageEntityTextUrl | MessageEntity.messageEntityMentionName | MessageEntity.inputMessageEntityMentionName | MessageEntity.messageEntityPhone | MessageEntity.messageEntityCashtag | MessageEntity.messageEntityUnderline | MessageEntity.messageEntityStrike | MessageEntity.messageEntityBlockquote | MessageEntity.messageEntityBankCard | MessageEntity.messageEntityEmoji | MessageEntity.messageEntityHighlight | MessageEntity.messageEntityLinebreak;
export namespace MessageEntity {
export type messageEntityUnknown = {
_: 'messageEntityUnknown',
offset: number,
length: number
length: number,
nested?: Array<MessageEntity>
};
export type messageEntityMention = {
_: 'messageEntityMention',
offset: number,
length: number
length: number,
nested?: Array<MessageEntity>
};
export type messageEntityHashtag = {
_: 'messageEntityHashtag',
offset: number,
length: number
length: number,
nested?: Array<MessageEntity>
};
export type messageEntityBotCommand = {
_: 'messageEntityBotCommand',
offset: number,
length: number
length: number,
nested?: Array<MessageEntity>
};
export type messageEntityUrl = {
_: 'messageEntityUrl',
offset: number,
length: number
length: number,
nested?: Array<MessageEntity>
};
export type messageEntityEmail = {
_: 'messageEntityEmail',
offset: number,
length: number
length: number,
nested?: Array<MessageEntity>
};
export type messageEntityBold = {
_: 'messageEntityBold',
offset: number,
length: number
length: number,
nested?: Array<MessageEntity>
};
export type messageEntityItalic = {
_: 'messageEntityItalic',
offset: number,
length: number
length: number,
nested?: Array<MessageEntity>
};
export type messageEntityCode = {
_: 'messageEntityCode',
offset: number,
length: number
length: number,
nested?: Array<MessageEntity>
};
export type messageEntityPre = {
_: 'messageEntityPre',
offset: number,
length: number,
language: string
language: string,
nested?: Array<MessageEntity>
};
export type messageEntityTextUrl = {
_: 'messageEntityTextUrl',
offset: number,
length: number,
url: string
url: string,
nested?: Array<MessageEntity>
};
export type messageEntityMentionName = {
_: 'messageEntityMentionName',
offset: number,
length: number,
user_id: number
user_id: number,
nested?: Array<MessageEntity>
};
export type inputMessageEntityMentionName = {
_: 'inputMessageEntityMentionName',
offset: number,
length: number,
user_id: InputUser
user_id: InputUser,
nested?: Array<MessageEntity>
};
export type messageEntityPhone = {
_: 'messageEntityPhone',
offset: number,
length: number
length: number,
nested?: Array<MessageEntity>
};
export type messageEntityCashtag = {
_: 'messageEntityCashtag',
offset: number,
length: number
length: number,
nested?: Array<MessageEntity>
};
export type messageEntityUnderline = {
_: 'messageEntityUnderline',
offset: number,
length: number
length: number,
nested?: Array<MessageEntity>
};
export type messageEntityStrike = {
_: 'messageEntityStrike',
offset: number,
length: number
length: number,
nested?: Array<MessageEntity>
};
export type messageEntityBlockquote = {
_: 'messageEntityBlockquote',
offset: number,
length: number
length: number,
nested?: Array<MessageEntity>
};
export type messageEntityBankCard = {
_: 'messageEntityBankCard',
offset: number,
length: number
length: number,
nested?: Array<MessageEntity>
};
export type messageEntityEmoji = {
_: 'messageEntityEmoji',
offset?: number,
length?: number,
unicode?: string,
nested?: Array<MessageEntity>
};
export type messageEntityHighlight = {
_: 'messageEntityHighlight',
offset?: number,
length?: number,
nested?: Array<MessageEntity>
};
export type messageEntityLinebreak = {
_: 'messageEntityLinebreak',
offset?: number,
length?: number,
nested?: Array<MessageEntity>
};
}
@ -8918,6 +8959,9 @@ export interface ConstructorDeclMap { @@ -8918,6 +8959,9 @@ export interface ConstructorDeclMap {
'messageReplyHeader': MessageReplyHeader.messageReplyHeader,
'messageReplies': MessageReplies.messageReplies,
'peerBlocked': PeerBlocked.peerBlocked,
'messageEntityEmoji': MessageEntity.messageEntityEmoji,
'messageEntityHighlight': MessageEntity.messageEntityHighlight,
'messageEntityLinebreak': MessageEntity.messageEntityLinebreak,
}
export type InvokeAfterMsg = {

2
src/lib/appManagers/appDialogsManager.ts

@ -674,7 +674,7 @@ export class AppDialogsManager { @@ -674,7 +674,7 @@ export class AppDialogsManager {
let lastMessageText = appMessagesManager.getRichReplyText(lastMessage, '');
let messageText = lastMessage.message;
let entities = RichTextProcessor.parseEntities(messageText.replace(/\n/g, ' '), {noLinebreakers: true});
let entities = RichTextProcessor.parseEntities(messageText.replace(/\n/g, ' '));
let regExp = new RegExp(escapeRegExp(highlightWord), 'gi');
let match: any;

2
src/lib/appManagers/appMessagesManager.ts

@ -2498,7 +2498,7 @@ export class AppMessagesManager { @@ -2498,7 +2498,7 @@ export class AppMessagesManager {
// * 80 for chatlist in landscape orientation
text = limitSymbols(text, 75, 80);
let entities = RichTextProcessor.parseEntities(text.replace(/\n/g, ' '), {noLinebreakers: true});
let entities = RichTextProcessor.parseEntities(text.replace(/\n/g, ' '));
messageWrapped = RichTextProcessor.wrapRichText(text, {
noLinebreaks: true,

353
src/lib/richtextprocessor.ts

@ -4,18 +4,17 @@ import Config from './config'; @@ -4,18 +4,17 @@ import Config from './config';
import emojiRegExp from '../emoji/regex';
import { encodeEmoji } from '../emoji';
import { MOUNT_CLASS_TO } from './mtproto/mtproto_config';
import { MessageEntity } from '../layer';
var EmojiHelper = {
const EmojiHelper = {
emojiMap: (code: string) => { return code; },
shortcuts: [] as any,
emojis: [] as any
};
var emojiData = Config.Emoji;
var emojiSupported = navigator.userAgent.search(/OS X|iPhone|iPad|iOS/i) != -1/* && false *//* || true */,
emojiCode;
const emojiData = Config.Emoji;
var alphaCharsRegExp = 'a-z' +
const alphaCharsRegExp = 'a-z' +
'\\u00c0-\\u00d6\\u00d8-\\u00f6\\u00f8-\\u00ff' + // Latin-1
'\\u0100-\\u024f' + // Latin Extended A and B
'\\u0253\\u0254\\u0256\\u0257\\u0259\\u025b\\u0263\\u0268\\u026f\\u0272\\u0289\\u028b' + // IPA Extensions
@ -40,10 +39,10 @@ var alphaCharsRegExp = 'a-z' + @@ -40,10 +39,10 @@ var alphaCharsRegExp = 'a-z' +
'\\uff21-\\uff3a\\uff41-\\uff5a' + // full width Alphabet
'\\uff66-\\uff9f' + // half width Katakana
'\\uffa1-\\uffdc'; // half width Hangul (Korean)
var alphaNumericRegExp = '0-9\_' + alphaCharsRegExp;
var domainAddChars = '\u00b7';
const alphaNumericRegExp = '0-9\_' + alphaCharsRegExp;
const domainAddChars = '\u00b7';
// Based on Regular Expression for URL validation by Diego Perini
var urlRegExp = '((?:https?|ftp)://|mailto:)?' +
const urlRegExp = '((?:https?|ftp)://|mailto:)?' +
// user:pass authentication
'(?:\\S{1,64}(?::\\S{0,64})?@)?' +
'(?:' +
@ -61,32 +60,35 @@ var urlRegExp = '((?:https?|ftp)://|mailto:)?' + @@ -61,32 +60,35 @@ var urlRegExp = '((?:https?|ftp)://|mailto:)?' +
'(?::\\d{2,5})?' +
// resource path
'(?:/(?:\\S{0,255}[^\\s.;,(\\[\\]{}<>"\'])?)?';
var usernameRegExp = '[a-zA-Z\\d_]{5,32}';
var botCommandRegExp = '\\/([a-zA-Z\\d_]{1,32})(?:@(' + usernameRegExp + '))?(\\b|$)';
var fullRegExp = new RegExp('(^| )(@)(' + usernameRegExp + ')|(' + urlRegExp + ')|(\\n)|(' + emojiRegExp + ')|(^|[\\s\\(\\]])(#[' + alphaNumericRegExp + ']{2,64})|(^|\\s)' + botCommandRegExp, 'i')
var emailRegExp = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
var markdownTestRegExp = /[`_*@]/;
var markdownRegExp = /(^|\s|\n)(````?)([\s\S]+?)(````?)([\s\n\.,:?!;]|$)|(^|\s)(`|\*\*|__)([^\n]+?)\7([\s\.,:?!;]|$)|@(\d+)\s*\((.+?)\)/m;
var siteHashtags: any = {
const usernameRegExp = '[a-zA-Z\\d_]{5,32}';
const botCommandRegExp = '\\/([a-zA-Z\\d_]{1,32})(?:@(' + usernameRegExp + '))?(\\b|$)';
const fullRegExp = new RegExp('(^| )(@)(' + usernameRegExp + ')|(' + urlRegExp + ')|(\\n)|(' + emojiRegExp + ')|(^|[\\s\\(\\]])(#[' + alphaNumericRegExp + ']{2,64})|(^|\\s)' + botCommandRegExp, 'i')
const emailRegExp = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const markdownTestRegExp = /[`_*@]/;
const markdownRegExp = /(^|\s|\n)(````?)([\s\S]+?)(````?)([\s\n\.,:?!;]|$)|(^|\s)(`|\*\*|__)([^\n]+?)\7([\s\.,:?!;]|$)|@(\d+)\s*\((.+?)\)/m;
const siteHashtags: {[siteName: string]: string} = {
Telegram: 'tg://search_hashtag?hashtag={1}',
Twitter: 'https://twitter.com/hashtag/{1}',
Instagram: 'https://instagram.com/explore/tags/{1}/',
'Google Plus': 'https://plus.google.com/explore/{1}'
};
var siteMentions: any = {
const siteMentions: {[siteName: string]: string} = {
Telegram: '#/im?p=%40{1}',
Twitter: 'https://twitter.com/{1}',
Instagram: 'https://instagram.com/{1}/',
GitHub: 'https://github.com/{1}'
};
var markdownEntities = {
const markdownEntities = {
'`': 'messageEntityCode',
'**': 'messageEntityBold',
'__': 'messageEntityItalic'
};
function getEmojiSpritesheetCoords(emojiCode: string) {
namespace RichTextProcessor {
export const emojiSupported = navigator.userAgent.search(/OS X|iPhone|iPad|iOS/i) != -1/* && false *//* || true */;
export function getEmojiSpritesheetCoords(emojiCode: string) {
let unified = encodeEmoji(emojiCode)/* .replace(/(-fe0f|fe0f)/g, '') */;
if(unified == '1f441-200d-1f5e8') {
@ -100,11 +102,13 @@ function getEmojiSpritesheetCoords(emojiCode: string) { @@ -100,11 +102,13 @@ function getEmojiSpritesheetCoords(emojiCode: string) {
}
return unified.replace(/(-fe0f|fe0f)/g, '');
}
function parseEntities(text: string, options = {}) {
}
export function parseEntities(text: string) {
var match;
var raw = text, url;
var entities = [], matchIndex;
const entities: MessageEntity[] = [];
let matchIndex;
var rawOffset = 0;
// var start = tsNow()
while((match = raw.match(fullRegExp))) {
@ -173,11 +177,11 @@ function parseEntities(text: string, options = {}) { @@ -173,11 +177,11 @@ function parseEntities(text: string, options = {}) {
unicode: emojiCoords
});
}
} else if(match[10]) { // Hashtag
} else if(match[11]) { // Hashtag
entities.push({
_: 'messageEntityHashtag',
offset: matchIndex + (match[9] ? match[9].length : 0),
length: match[10].length
offset: matchIndex + (match[10] ? match[10].length : 0),
length: match[11].length
});
} else if(match[12]) { // Bot command
entities.push({
@ -194,9 +198,10 @@ function parseEntities(text: string, options = {}) { @@ -194,9 +198,10 @@ function parseEntities(text: string, options = {}) {
// if (entities.length) {
// console.log('parse entities', text, entities.slice())
// }
return entities
}
function parseEmojis(text: string) {
return entities;
}
/* export function parseEmojis(text: string) {
return text.replace(/:([a-z0-9\-\+\*_]+?):/gi, function (all, shortcut) {
var emojiCode = EmojiHelper.shortcuts[shortcut]
if (emojiCode !== undefined) {
@ -204,9 +209,10 @@ function parseEmojis(text: string) { @@ -204,9 +209,10 @@ function parseEmojis(text: string) {
}
return all
})
}
function parseMarkdown(text: string, entities: any[], noTrim?: any) {
  if(!markdownTestRegExp.test(text)) {
} */
export function parseMarkdown(text: string, entities: MessageEntity[], noTrim?: any) {
  if(!markdownTestRegExp.test(text)) {
return noTrim ? text : text.trim();
}
@ -251,7 +257,7 @@ function parseMarkdown(text: string, entities: any[], noTrim?: any) { @@ -251,7 +257,7 @@ function parseMarkdown(text: string, entities: any[], noTrim?: any) {
newText.push(text)
entities.push({
_: 'messageEntityMentionName',
user_id: match[10],
user_id: +match[10],
offset: matchIndex,
length: text.length
})
@ -270,34 +276,27 @@ function parseMarkdown(text: string, entities: any[], noTrim?: any) { @@ -270,34 +276,27 @@ function parseMarkdown(text: string, entities: any[], noTrim?: any) {
newText = newText.trim()
}
return newText
}
function mergeEntities(currentEntities: any[], newEntities: any[], fromApi: any) {
var totalEntities = newEntities.slice();
var i;
var len = currentEntities.length;
var j;
var len2 = newEntities.length;
var startJ = 0;
var curEntity;
var newEntity;
var start, end;
var cStart, cEnd;
var bad;
for(i = 0; i < len; i++) {
curEntity = currentEntities[i];
if (fromApi &&
}
export function mergeEntities(currentEntities: MessageEntity[], newEntities: MessageEntity[], fromApi?: boolean) {
const totalEntities = newEntities.slice();
const newLength = newEntities.length;
let startJ = 0;
for(let i = 0, length = currentEntities.length; i < length; i++) {
const curEntity = currentEntities[i];
/* if(fromApi &&
curEntity._ != 'messageEntityLinebreak' &&
curEntity._ != 'messageEntityEmoji') {
continue;
}
} */
// console.log('s', curEntity, newEntities);
start = curEntity.offset;
end = start + curEntity.length;
bad = false;
for(j = startJ; j < len2; j++) {
newEntity = newEntities[j];
cStart = newEntity.offset;
cEnd = cStart + newEntity.length;
const start = curEntity.offset;
const end = start + curEntity.length;
let bad = false;
for(let j = startJ; j < newLength; j++) {
const newEntity = newEntities[j];
const cStart = newEntity.offset;
const cEnd = cStart + newEntity.length;
if(cStart <= start) {
startJ = j;
}
@ -305,8 +304,7 @@ function mergeEntities(currentEntities: any[], newEntities: any[], fromApi: any) @@ -305,8 +304,7 @@ function mergeEntities(currentEntities: any[], newEntities: any[], fromApi: any)
if(start >= cStart && start < cEnd ||
end > cStart && end <= cEnd) {
// console.log('bad', curEntity, newEntity)
if(fromApi &&
start >= cStart && end <= cEnd) {
if(fromApi && start >= cStart && end <= cEnd) {
if(newEntity.nested === undefined) {
newEntity.nested = [];
}
@ -336,17 +334,19 @@ function mergeEntities(currentEntities: any[], newEntities: any[], fromApi: any) @@ -336,17 +334,19 @@ function mergeEntities(currentEntities: any[], newEntities: any[], fromApi: any)
});
// console.log('merge', currentEntities, newEntities, totalEntities)
return totalEntities;
}
function wrapRichNestedText(text: string, nested: any, options: any) {
}
export function wrapRichNestedText(text: string, nested: MessageEntity[], options: any) {
if(nested === undefined) {
return encodeEntities(text);
}
options.hasNested = true;
return wrapRichText(text, {entities: nested, nested: true});
}
function wrapRichText(text: string, options: Partial<{
entities: any,
}
export function wrapRichText(text: string, options: Partial<{
entities: MessageEntity[],
contextSite: string,
highlightUsername: string,
noLinks: boolean,
@ -356,29 +356,20 @@ function wrapRichText(text: string, options: Partial<{ @@ -356,29 +356,20 @@ function wrapRichText(text: string, options: Partial<{
noTextFormat: boolean,
nested?: boolean,
contextHashtag?: string
}> = {}) {
}> = {}) {
if(!text || !text.length) {
return ''
return '';
}
var entities = options.entities;
var contextSite = options.contextSite || 'Telegram';
var contextExternal = contextSite != 'Telegram';
var emojiFound = false;
if(entities === undefined) {
entities = parseEntities(text, options);
}
const entities = options.entities || parseEntities(text);
const contextSite = options.contextSite || 'Telegram';
const contextExternal = contextSite != 'Telegram';
//console.log('wrapRichText got entities:', text, entities);
var len = entities.length;
var entity;
var entityText;
var skipEntity;
var url;
var html = [];
var lastOffset = 0;
for(var i = 0; i < len; i++) {
entity = entities[i];
const html: string[] = [];
let lastOffset = 0;
for(let i = 0, len = entities.length; i < len; i++) {
const entity = entities[i];
if(entity.offset > lastOffset) {
html.push(
encodeEntities(text.substr(lastOffset, entity.offset - lastOffset))
@ -387,8 +378,8 @@ function wrapRichText(text: string, options: Partial<{ @@ -387,8 +378,8 @@ function wrapRichText(text: string, options: Partial<{
continue;
}
skipEntity = false;
entityText = text.substr(entity.offset, entity.length);
let skipEntity = false;
const entityText = text.substr(entity.offset, entity.length);
switch(entity._) {
case 'messageEntityMention':
var contextUrl = !options.noLinks && siteMentions[contextSite]
@ -412,27 +403,31 @@ function wrapRichText(text: string, options: Partial<{ @@ -412,27 +403,31 @@ function wrapRichText(text: string, options: Partial<{
encodeEntities(entityText),
'</a>'
)
break
break;
case 'messageEntityMentionName':
if (options.noLinks) {
skipEntity = true
break
if(options.noLinks) {
skipEntity = true;
break;
}
html.push(
'<a href="#/im?p=u',
encodeURIComponent(entity.user_id),
'">',
encodeEntities(entityText),
'</a>'
)
break
);
break;
case 'messageEntityHashtag':
var contextUrl = !options.noLinks && siteHashtags[contextSite]
if (!contextUrl) {
skipEntity = true
break
var contextUrl = !options.noLinks && siteHashtags[contextSite];
if(!contextUrl) {
skipEntity = true;
break;
}
var hashtag = entityText.substr(1)
var hashtag = entityText.substr(1);
html.push(
'<a ',
contextExternal ? ' target="_blank" rel="noopener noreferrer" ' : '',
@ -442,33 +437,38 @@ function wrapRichText(text: string, options: Partial<{ @@ -442,33 +437,38 @@ function wrapRichText(text: string, options: Partial<{
'">',
encodeEntities(entityText),
'</a>'
)
break
);
break;
case 'messageEntityEmail':
if (options.noLinks) {
skipEntity = true
break
if(options.noLinks) {
skipEntity = true;
break;
}
html.push(
'<a href="',
encodeEntities('mailto:' + entityText),
'" target="_blank" rel="noopener noreferrer">',
encodeEntities(entityText),
'</a>'
)
break
);
break;
case 'messageEntityUrl':
case 'messageEntityTextUrl':
var inner
let inner: string;
let url: string;
if (entity._ == 'messageEntityTextUrl') {
url = entity.url
url = wrapUrl(url, true)
inner = wrapRichNestedText(entityText, entity.nested, options)
url = (entity as MessageEntity.messageEntityTextUrl).url;
url = wrapUrl(url, true);
inner = wrapRichNestedText(entityText, entity.nested, options);
} else {
url = wrapUrl(entityText, false)
inner = encodeEntities(replaceUrlEncodings(entityText))
url = wrapUrl(entityText, false);
inner = encodeEntities(replaceUrlEncodings(entityText));
}
if (options.noLinks) {
if(options.noLinks) {
html.push(inner);
} else {
html.push(
@ -477,41 +477,45 @@ function wrapRichText(text: string, options: Partial<{ @@ -477,41 +477,45 @@ function wrapRichText(text: string, options: Partial<{
'" target="_blank" rel="noopener noreferrer">',
inner,
'</a>'
)
);
}
break
break;
case 'messageEntityLinebreak':
html.push(options.noLinebreaks ? ' ' : '<br/>')
break
html.push(options.noLinebreaks ? ' ' : '<br/>');
break;
case 'messageEntityEmoji':
html.push(emojiSupported ?
`<span class="emoji" contenteditable="false">${encodeEntities(entityText)}</span>` :
`<img src="assets/img/emoji/${entity.unicode}.png" alt="${encodeEntities(entityText)}" class="emoji">`);
break;
emojiFound = true;
break
case 'messageEntityBotCommand':
if (options.noLinks || options.noCommands || contextExternal) {
skipEntity = true
break
if(options.noLinks || options.noCommands || contextExternal) {
skipEntity = true;
break;
}
var command = entityText.substr(1)
var bot
var atPos
var command = entityText.substr(1);
var bot;
var atPos;
if ((atPos = command.indexOf('@')) != -1) {
bot = command.substr(atPos + 1)
command = command.substr(0, atPos)
bot = command.substr(atPos + 1);
command = command.substr(0, atPos);
} else {
bot = options.fromBot
bot = options.fromBot;
}
html.push(
'<a href="',
encodeEntities('tg://bot_command?command=' + encodeURIComponent(command) + (bot ? '&bot=' + encodeURIComponent(bot) : '')),
'">',
encodeEntities(entityText),
'</a>'
)
break
);
break;
case 'messageEntityBold':
if(options.noTextFormat) {
html.push(wrapRichNestedText(entityText, entity.nested, options));
@ -522,8 +526,9 @@ function wrapRichText(text: string, options: Partial<{ @@ -522,8 +526,9 @@ function wrapRichText(text: string, options: Partial<{
'<strong>',
wrapRichNestedText(entityText, entity.nested, options),
'</strong>'
)
break
);
break;
case 'messageEntityItalic':
if(options.noTextFormat) {
html.push(wrapRichNestedText(entityText, entity.nested, options));
@ -534,15 +539,25 @@ function wrapRichText(text: string, options: Partial<{ @@ -534,15 +539,25 @@ function wrapRichText(text: string, options: Partial<{
'<em>',
wrapRichNestedText(entityText, entity.nested, options),
'</em>'
)
break
);
break;
case 'messageEntityHighlight':
html.push(
'<i>',
wrapRichNestedText(entityText, entity.nested, options),
'</i>'
)
);
break;
case 'messageEntityStrike':
html.push(
'<del>',
wrapRichNestedText(entityText, entity.nested, options),
'</del>'
);
break;
case 'messageEntityCode':
if(options.noTextFormat) {
html.push(encodeEntities(entityText));
@ -553,8 +568,9 @@ function wrapRichText(text: string, options: Partial<{ @@ -553,8 +568,9 @@ function wrapRichText(text: string, options: Partial<{
'<code>',
encodeEntities(entityText),
'</code>'
)
break
);
break;
case 'messageEntityPre':
if(options.noTextFormat) {
html.push(encodeEntities(entityText));
@ -565,33 +581,31 @@ function wrapRichText(text: string, options: Partial<{ @@ -565,33 +581,31 @@ function wrapRichText(text: string, options: Partial<{
'<pre><code', (entity.language ? ' class="language-' + encodeEntities(entity.language) + '"' : ''), '>',
encodeEntities(entityText),
'</code></pre>'
)
break
);
break;
default:
skipEntity = true
skipEntity = true;
}
lastOffset = entity.offset + (skipEntity ? 0 : entity.length)
lastOffset = entity.offset + (skipEntity ? 0 : entity.length);
}
html.push(encodeEntities(text.substr(lastOffset))); // may be empty string
//console.log(html);
text = html.join('')//$sanitize(html.join(''))
/* if (!options.nested && (emojiFound || options.hasNested)) {
text = text.replace(/\ufe0f|&#65039;|&#65533;|&#8205;/g, '', text)
var emojiSizeClass = curEmojiSize == 18 ? '' : (' emoji-w' + curEmojiSize)
text = text.replace(/<span((?: [^>]*)?) class="emoji emoji-(\d)-(\d+)-(\d+)"(.+?)<\/span>/g,
'<span$1 class="emoji ' + emojiSizeClass + ' emoji-spritesheet-$2" style="background-position: -$3px -$4px;" $5</span>')
} */
return text;//$sce.trustAs('html', text)
}
function wrapDraftText (text: string, options: any = {}) {
text = html.join('');
return text;
}
export function wrapDraftText(text: string, options: any = {}) {
if(!text || !text.length) {
return '';
}
var entities = options.entities;
if(entities === undefined) {
entities = parseEntities(text, options);
entities = parseEntities(text);
}
var i = 0;
var len = entities.length;
@ -658,8 +672,9 @@ function wrapDraftText (text: string, options: any = {}) { @@ -658,8 +672,9 @@ function wrapDraftText (text: string, options: any = {}) {
}
code.push(text.substr(lastOffset));
return code.join('');
}
function checkBrackets(url: string) {
}
export function checkBrackets(url: string) {
var urlLength = url.length;
var urlOpenBrackets = url.split('(').length - 1;
var urlCloseBrackets = url.split(')').length - 1;
@ -673,9 +688,9 @@ function checkBrackets(url: string) { @@ -673,9 +688,9 @@ function checkBrackets(url: string) {
url = url.replace(/\)+$/, '');
}
return url;
}
}
function replaceUrlEncodings(urlWithEncoded: string) {
export function replaceUrlEncodings(urlWithEncoded: string) {
return urlWithEncoded.replace(/(%[A-Z\d]{2})+/g, (str) => {
try {
return decodeURIComponent(str);
@ -683,9 +698,9 @@ function replaceUrlEncodings(urlWithEncoded: string) { @@ -683,9 +698,9 @@ function replaceUrlEncodings(urlWithEncoded: string) {
return str;
}
});
}
}
function wrapPlainText(text: any, options: any = {}) {
export function wrapPlainText(text: any) {
if(emojiSupported) {
return text;
}
@ -703,7 +718,8 @@ function wrapPlainText(text: any, options: any = {}) { @@ -703,7 +718,8 @@ function wrapPlainText(text: any, options: any = {}) {
text.push(raw.substr(0, match.index))
if(match[8]) {
// @ts-ignore
if((emojiCode = EmojiHelper.emojiMap[match[8]]) &&
const emojiCode = EmojiHelper.emojiMap[match[8]];
if(emojiCode &&
// @ts-ignore
(emojiTitle = emojiData[emojiCode][1][0])) {
text.push(':' + emojiTitle + ':');
@ -718,14 +734,16 @@ function wrapPlainText(text: any, options: any = {}) { @@ -718,14 +734,16 @@ function wrapPlainText(text: any, options: any = {}) {
}
text.push(raw);
return text.join('');
}
function wrapEmojiText(text: string) {
}
export function wrapEmojiText(text: string) {
if(!text) return '';
let entities = parseEntities(text).filter(e => e._ == 'messageEntityEmoji');
return wrapRichText(text, {entities});
}
function wrapUrl(url: string, unsafe: number | boolean): string {
}
export function wrapUrl(url: string, unsafe: number | boolean): string {
if(!url.match(/^https?:\/\//i)) {
url = 'http://' + url;
}
@ -775,28 +793,15 @@ function wrapUrl(url: string, unsafe: number | boolean): string { @@ -775,28 +793,15 @@ function wrapUrl(url: string, unsafe: number | boolean): string {
}
return url;
}
}
function matchUrl(text: string) {
export function matchUrl(text: string) {
return text.match(urlRegExp);
}
}
let RichTextProcessor = {
wrapRichText,
wrapPlainText,
wrapDraftText,
wrapUrl,
wrapEmojiText,
parseEntities,
parseMarkdown,
parseEmojis,
mergeEntities,
getEmojiSpritesheetCoords,
emojiSupported,
matchUrl
};
MOUNT_CLASS_TO && (MOUNT_CLASS_TO.RichTextProcessor = RichTextProcessor);
export {RichTextProcessor};
export default RichTextProcessor;

9
src/lib/services.ts

@ -34,7 +34,7 @@ const appSidebarLeft = AppSidebarLeft; @@ -34,7 +34,7 @@ const appSidebarLeft = AppSidebarLeft;
const appMediaViewer = AppMediaViewer;
const appDialogsManager = AppDialogsManager;
(window as any).Services = {
const Services = {
appUsersManager,
appChatsManager,
apiUpdatesManager,
@ -53,3 +53,10 @@ const appDialogsManager = AppDialogsManager; @@ -53,3 +53,10 @@ const appDialogsManager = AppDialogsManager;
appMediaViewer
//appSharedMediaManager
};
(window as any).Services = Services;
for(let i in Services) {
// @ts-ignore
(window as any)[i] = Services[i];
}

7
src/scripts/generate_mtproto_types.js

@ -10,7 +10,12 @@ for(const constructor of additional) { @@ -10,7 +10,12 @@ for(const constructor of additional) {
param.type = 'flags.-1?' + param.type;
});
const realConstructor = mtproto.constructors.find(c => c.predicate == constructor.predicate);
if(constructor.type) {
mtproto.constructors.push(constructor);
}
const realConstructor = constructor.type ? constructor : mtproto.constructors.find(c => c.predicate == constructor.predicate);
/* constructor.params.forEach(param => {
const index = realConstructor.params.findIndex(_param => _param.predicate == param.predicate);
if(index !== -1) {

120
src/scripts/in/schema_additional_params.json

@ -91,4 +91,124 @@ @@ -91,4 +91,124 @@
"params": [
{"name": "rAbout", "type": "string"}
]
}, {
"predicate": "messageEntityEmoji",
"params": [
{"name": "offset", "type": "number"},
{"name": "length", "type": "number"},
{"name": "unicode", "type": "string"},
{"name": "nested", "type": "Array<MessageEntity>"}
],
"type": "MessageEntity"
}, {
"predicate": "messageEntityHighlight",
"params": [
{"name": "offset", "type": "number"},
{"name": "length", "type": "number"},
{"name": "nested", "type": "Array<MessageEntity>"}
],
"type": "MessageEntity"
}, {
"predicate": "messageEntityLinebreak",
"params": [
{"name": "offset", "type": "number"},
{"name": "length", "type": "number"},
{"name": "nested", "type": "Array<MessageEntity>"}
],
"type": "MessageEntity"
}, {
"predicate": "messageEntityUnknown",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityMention",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityHashtag",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityBotCommand",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityUrl",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityEmail",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityBold",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityItalic",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityCode",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityPre",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityTextUrl",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityMentionName",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityPhone",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityCashtag",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityUnderline",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityStrike",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityBlockquote",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "messageEntityBankCard",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}, {
"predicate": "inputMessageEntityMentionName",
"params": [
{"name": "nested", "type": "Array<MessageEntity>"}
]
}]
Loading…
Cancel
Save