mirror of
https://github.com/divkit/divkit.git
synced 2026-05-07 20:02:32 +00:00
Update comments and remove old logic
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
// Стандартные снепшоты слишком точные для наших целей -
|
||||
// они снапшотят undefined поля, которых в карточках очень много
|
||||
// (в силу особенностей конструкторов блоков), читать
|
||||
// стандартный снапшот поэтому тяжело.
|
||||
// The standard snapshot serializer is too accurate for us
|
||||
// It stores all the "undefined" values, of which there are many in our data
|
||||
module.exports = {
|
||||
serialize(val) {
|
||||
return JSON.stringify(val, null, 2);
|
||||
|
||||
@@ -12,10 +12,9 @@ type Exactly<TBase, TExt extends TBase> = {
|
||||
export type IntBoolean = 1 | 0;
|
||||
|
||||
/**
|
||||
* DFS-Обход js-объекта как дерева с выполнением в каждом
|
||||
* узле заданного действия
|
||||
* @param tree js-объект
|
||||
* @param nodeAction действие, выполняемое для каждого узла дерева
|
||||
* DFS for a js object with callback on each leaf
|
||||
* @param tree js object
|
||||
* @param nodeAction callback for each leaf
|
||||
*/
|
||||
export function treeWalkDFS(tree: unknown, nodeAction: (x: unknown, path: string[]) => void): void {
|
||||
const stack: [unknown, string[]][] = [[tree, []]];
|
||||
|
||||
@@ -3,26 +3,14 @@ import { treeWalkDFS } from './helper';
|
||||
import { ITemplates, TemplateBlock } from './template';
|
||||
|
||||
/**
|
||||
* Проверяет имя шаблона и возвращает true,
|
||||
* если имя шаблона нужно сохранить.
|
||||
* Например, в веб-морде есть 'мета-шаблон'
|
||||
* home:block, который нельзя переименовывать
|
||||
*/
|
||||
export function isExternalTemplate(templateName: string): boolean {
|
||||
return templateName.startsWith('home:');
|
||||
}
|
||||
|
||||
/**
|
||||
* Поиск вложенных шаблонов для заданного шаблона
|
||||
* @param name - имя заданного шаблона
|
||||
* @param templates - список всех шаблонов для проверки
|
||||
* разрешимости зависимостей
|
||||
* Search for a used templates list
|
||||
* @param template
|
||||
*/
|
||||
function findPlainDeps(template: Div): Set<string> {
|
||||
const deps = new Set<string>();
|
||||
|
||||
treeWalkDFS(template, (node) => {
|
||||
if (node instanceof TemplateBlock && !isExternalTemplate(node.type)) {
|
||||
if (node instanceof TemplateBlock) {
|
||||
deps.add(node.type);
|
||||
}
|
||||
});
|
||||
@@ -41,12 +29,10 @@ export type TemplateResolvedAction<T> = (props: {
|
||||
}) => T;
|
||||
|
||||
/**
|
||||
* Обход шаблонов с разрешением зависимостей
|
||||
* перед выполнением действия
|
||||
* Templates walker. It resolves template dependencies on each step, and also can run a callback after that
|
||||
* @param templates
|
||||
* @param resolvedAction действие выполнямое для шаблона,
|
||||
* когда все его зависимости разрешены
|
||||
* @param depsResolved ранее разрешенные зависимости, например для общих шаблонов
|
||||
* @param resolvedAction Callback for the template. It will be called after resolving dependencies
|
||||
* @param depsResolved Deps resolve cache, for example, for common templates
|
||||
*/
|
||||
export function runResolveDeps<T>(
|
||||
templates: ITemplates,
|
||||
@@ -95,9 +81,10 @@ export function runResolveDeps<T>(
|
||||
}
|
||||
|
||||
/**
|
||||
* Поиск зависимостей шаблонов
|
||||
* @param templates шаблоны
|
||||
* @returns для каждого шаблона список его зависимостей
|
||||
* Search for a templates dependencies
|
||||
* @param templates
|
||||
* @param depsResolved Deps resolution cache
|
||||
* @returns Map with deps for each template
|
||||
*/
|
||||
export function templatesDepsMap(
|
||||
templates: ITemplates,
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import { copyTemplates, treeWalkDFS } from './helper';
|
||||
import { ITemplates, TemplateBlock } from './template';
|
||||
import { isExternalTemplate, runResolveDeps } from './template-helper-deps';
|
||||
import { runResolveDeps } from './template-helper-deps';
|
||||
|
||||
/**
|
||||
* Переписывание шаблонов с заменой имен вложенных шаблонов
|
||||
* Например, в шаблоне
|
||||
* Templates rewriting for a nested templates
|
||||
* For example, in template
|
||||
* new DivContainer({
|
||||
* items: [
|
||||
* template('template2')
|
||||
* ]
|
||||
* })
|
||||
* 'template2' будет заменен на `template2/${hash(templates.template2)}`
|
||||
* @param templates шаблоны для перезаписи
|
||||
* @param rename функция, возвращающая новое имя
|
||||
* @param depsResolved ранее вычисленные имена, например общих шаблонов
|
||||
* @returns переписанные шаблоны + хэшмап новых имен
|
||||
* 'template2' would be replaces into `template2/${hash(templates.template2)}`
|
||||
* @param templates Templates to process
|
||||
* @param rename New name generator
|
||||
* @param resolvedNames Rename cache
|
||||
* @returns Processed templates + map with transformed names
|
||||
*/
|
||||
export function rewriteNames<T extends ITemplates>(
|
||||
templates: T,
|
||||
@@ -30,7 +30,7 @@ export function rewriteNames<T extends ITemplates>(
|
||||
templates,
|
||||
({ name, template, depsResolved }) => {
|
||||
treeWalkDFS(template, (node) => {
|
||||
if (node instanceof TemplateBlock && !isExternalTemplate(node.type)) {
|
||||
if (node instanceof TemplateBlock) {
|
||||
(node as any).type = depsResolved[node.type];
|
||||
}
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ function rewriteRefsTemplate(template: unknown): void {
|
||||
const objChild = obj[key];
|
||||
if (objChild && typeof objChild === 'object') {
|
||||
if (objChild instanceof TemplatePropertyReference) {
|
||||
obj[key] = undefined; // delete ломает валидатор
|
||||
obj[key] = undefined;
|
||||
|
||||
if (objChild.templatePropertyName !== key) {
|
||||
obj['$' + key] = objChild.templatePropertyName;
|
||||
@@ -27,12 +27,14 @@ function rewriteRefsTemplate(template: unknown): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* Заменяет в шаблонах замену параметры вида
|
||||
* Changes the reference-objects with the actual props
|
||||
*
|
||||
* Example:
|
||||
* prop: reference('template_prop')
|
||||
* на
|
||||
* to
|
||||
* $prop: 'template_prop'
|
||||
* @param templates Шаблоны
|
||||
* @returns Шаблоны, готовые для сериализации в формате DivKit
|
||||
* @param templates
|
||||
* @returns Serialization-ready templates
|
||||
*/
|
||||
export function rewriteRefs<T extends ITemplates>(templates: T): T {
|
||||
const result = copyTemplates(templates);
|
||||
|
||||
@@ -28,12 +28,11 @@ export function thelperVersion(templates: ITemplates): (name: string) => string
|
||||
}
|
||||
|
||||
/**
|
||||
* Переписывает вызовы TemplateBlock в шаблонах,
|
||||
* добавляя к их именам версии (md5 хэш).
|
||||
* Имена корневых шаблонов (ключи объекта templates) не меняются!
|
||||
* @param templates шаблоны
|
||||
* @param resolvedNames ранее вычисленные имена, например общих шаблонов
|
||||
* @returns хэшмап новых имен шаблонов
|
||||
* Replaces a TemplateBlock calls with the concat of the name with a hash (md5).
|
||||
* The names of the root templates are not changed! (templates object keys)
|
||||
* @param templates
|
||||
* @param resolvedNames Names cache
|
||||
* @returns A map with new names
|
||||
*/
|
||||
export function rewriteTemplateVersions<T extends ITemplates>(
|
||||
templates: T,
|
||||
|
||||
@@ -29,7 +29,7 @@ type TemplateVars<T, X> = T extends TemplateBlock<infer K2, any>
|
||||
: {}
|
||||
: Vars<T, X>;
|
||||
|
||||
// Переход от A | B | C к Vars<A> | Vars<B> | Vars<C>
|
||||
// Transforms "A | B | C" into the "Vars<A> | Vars<B> | Vars<C>"
|
||||
type DistributeTemplateVars<T, X> = UnionToIntersection<T extends any ? TemplateVars<T, X> : never>;
|
||||
|
||||
type Vars<T, X> = '_props' extends keyof T
|
||||
|
||||
@@ -503,7 +503,7 @@ exports[`DivCard tests should create POI card 1`] = `
|
||||
"title_items": [
|
||||
{
|
||||
"type": "title_text",
|
||||
"text": "Рядом с вами"
|
||||
"text": "Around"
|
||||
},
|
||||
{
|
||||
"type": "title_menu",
|
||||
@@ -511,14 +511,14 @@ exports[`DivCard tests should create POI card 1`] = `
|
||||
"log_id": "menu",
|
||||
"menu_items": [
|
||||
{
|
||||
"text": "Настройки ленты",
|
||||
"text": "Feed options",
|
||||
"action": {
|
||||
"url": "http://ya.ru",
|
||||
"log_id": "settings"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": "Скрыть карточку",
|
||||
"text": "Hide the card",
|
||||
"action": {
|
||||
"url": "http://ya.ru",
|
||||
"log_id": "hide"
|
||||
@@ -528,10 +528,10 @@ exports[`DivCard tests should create POI card 1`] = `
|
||||
}
|
||||
}
|
||||
],
|
||||
"footer_text": "ОТКРЫТЬ КАРТЫ",
|
||||
"footer_text": "OPEN MAPS",
|
||||
"tab_items_link": [
|
||||
{
|
||||
"title": "ПОПУЛЯРНОЕ",
|
||||
"title": "POPULAR",
|
||||
"div": {
|
||||
"type": "gallery",
|
||||
"height": {
|
||||
@@ -542,13 +542,13 @@ exports[`DivCard tests should create POI card 1`] = `
|
||||
"items": [
|
||||
{
|
||||
"type": "poi_gallery_item",
|
||||
"badge_text": "Лучшее",
|
||||
"badge_text": "Best",
|
||||
"background_url": "https://avatars.mds.yandex.net/get-pdb/1340633/88a085e7-7254-43ff-805a-660b96f0e6ce/s1200?webp=false",
|
||||
"place_category": "РЕСТОРАН",
|
||||
"place_title": "Кулинарная лавка",
|
||||
"address": "улица Тимура Фрунзе, 11, корп. 8",
|
||||
"time": "ДО 23:00",
|
||||
"distance": "150м",
|
||||
"place_category": "RESTAURANT",
|
||||
"place_title": "Bakery",
|
||||
"address": "221b, Baker Street",
|
||||
"time": "till 23:00",
|
||||
"distance": "150m",
|
||||
"poi_stars": [
|
||||
{
|
||||
"type": "star_full"
|
||||
@@ -570,19 +570,19 @@ exports[`DivCard tests should create POI card 1`] = `
|
||||
},
|
||||
{
|
||||
"type": "poi_gallery_item",
|
||||
"badge_text": "Лучшее",
|
||||
"badge_text": "Best",
|
||||
"background_url": "https://avatars.mds.yandex.net/get-pdb/1340633/88a085e7-7254-43ff-805a-660b96f0e6ce/s1200?webp=false",
|
||||
"place_category": "КОНЦЕРТ",
|
||||
"place_title": "Black Label Society",
|
||||
"address": "чт 15 февраля",
|
||||
"time": "Главclub Green Concert",
|
||||
"distance": "150м",
|
||||
"place_category": "CONCERT",
|
||||
"place_title": "Violin concert",
|
||||
"address": "221b, Baker Street",
|
||||
"time": "21:30",
|
||||
"distance": "150m",
|
||||
"poi_stars": [],
|
||||
"poi_gallery_item_action_link": "ya.ru"
|
||||
},
|
||||
{
|
||||
"type": "gallery_tail_light",
|
||||
"tail_text_link": "Ещё на картах",
|
||||
"tail_text_link": "More",
|
||||
"visibility_action": {
|
||||
"log_id": "a66",
|
||||
"visibility_duration": 10000
|
||||
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Rewrite templates should shoud preserve home:block 1`] = `
|
||||
{
|
||||
"block1": {
|
||||
"type": "container",
|
||||
"items": [
|
||||
{
|
||||
"type": "block2/test"
|
||||
},
|
||||
{
|
||||
"type": "block3/test"
|
||||
}
|
||||
]
|
||||
},
|
||||
"block2": {
|
||||
"type": "container",
|
||||
"items": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "text1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"block3": {
|
||||
"type": "block2/test"
|
||||
},
|
||||
"block4": {
|
||||
"type": "home:block"
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -264,21 +264,21 @@ describe('DivCard tests', (): void => {
|
||||
div: template('poi_card', {
|
||||
title_items: [
|
||||
template('title_text', {
|
||||
text: 'Рядом с вами',
|
||||
text: 'Around',
|
||||
}),
|
||||
template('title_menu', {
|
||||
action: {
|
||||
log_id: 'menu',
|
||||
menu_items: [
|
||||
{
|
||||
text: 'Настройки ленты',
|
||||
text: 'Feed options',
|
||||
action: {
|
||||
url: 'http://ya.ru',
|
||||
log_id: 'settings',
|
||||
},
|
||||
},
|
||||
{
|
||||
text: 'Скрыть карточку',
|
||||
text: 'Hide the card',
|
||||
action: {
|
||||
url: 'http://ya.ru',
|
||||
log_id: 'hide',
|
||||
@@ -288,10 +288,10 @@ describe('DivCard tests', (): void => {
|
||||
},
|
||||
}),
|
||||
],
|
||||
footer_text: 'ОТКРЫТЬ КАРТЫ',
|
||||
footer_text: 'OPEN MAPS',
|
||||
tab_items_link: [
|
||||
{
|
||||
title: 'ПОПУЛЯРНОЕ',
|
||||
title: 'POPULAR',
|
||||
div: new DivGallery({
|
||||
width: weighted(40),
|
||||
height: fixed(240, 'sp'),
|
||||
@@ -301,14 +301,14 @@ describe('DivCard tests', (): void => {
|
||||
},
|
||||
items: [
|
||||
template('poi_gallery_item', {
|
||||
badge_text: 'Лучшее',
|
||||
badge_text: 'Best',
|
||||
background_url:
|
||||
'https://avatars.mds.yandex.net/get-pdb/1340633/88a085e7-7254-43ff-805a-660b96f0e6ce/s1200?webp=false',
|
||||
place_category: 'РЕСТОРАН',
|
||||
place_title: 'Кулинарная лавка',
|
||||
address: 'улица Тимура Фрунзе, 11, корп. 8',
|
||||
time: 'ДО 23:00',
|
||||
distance: '150м',
|
||||
place_category: 'RESTAURANT',
|
||||
place_title: 'Bakery',
|
||||
address: '221b, Baker Street',
|
||||
time: 'till 23:00',
|
||||
distance: '150m',
|
||||
poi_stars: [
|
||||
{
|
||||
type: 'star_full',
|
||||
@@ -329,19 +329,19 @@ describe('DivCard tests', (): void => {
|
||||
poi_gallery_item_action_link: 'ya.ru',
|
||||
}),
|
||||
template('poi_gallery_item', {
|
||||
badge_text: 'Лучшее',
|
||||
badge_text: 'Best',
|
||||
background_url:
|
||||
'https://avatars.mds.yandex.net/get-pdb/1340633/88a085e7-7254-43ff-805a-660b96f0e6ce/s1200?webp=false',
|
||||
place_category: 'КОНЦЕРТ',
|
||||
place_title: 'Black Label Society',
|
||||
address: 'чт 15 февраля',
|
||||
time: 'Главclub Green Concert',
|
||||
distance: '150м',
|
||||
place_category: 'CONCERT',
|
||||
place_title: 'Violin concert',
|
||||
address: '221b, Baker Street',
|
||||
time: '21:30',
|
||||
distance: '150m',
|
||||
poi_stars: [],
|
||||
poi_gallery_item_action_link: 'ya.ru',
|
||||
}),
|
||||
template('gallery_tail_light', {
|
||||
tail_text_link: 'Ещё на картах',
|
||||
tail_text_link: 'More',
|
||||
visibility_action: {
|
||||
log_id: 'a66',
|
||||
visibility_duration: 10000,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { DivContainer, DivText, template, templatesDepsMap } from '../../src';
|
||||
describe('template deps', () => {
|
||||
it('should find templates deps', () => {
|
||||
const templates = {
|
||||
template1: template('home:block', {
|
||||
template1: template('template2', {
|
||||
items: [template('template2'), template('template5')],
|
||||
}),
|
||||
template2: new DivContainer({
|
||||
@@ -11,7 +11,7 @@ describe('template deps', () => {
|
||||
}),
|
||||
template3: new DivContainer({
|
||||
items: [
|
||||
template('home:test'),
|
||||
template('template5'),
|
||||
new DivContainer({
|
||||
items: [template('template4')],
|
||||
}),
|
||||
@@ -30,8 +30,8 @@ describe('template deps', () => {
|
||||
expect(new Set(depsMap.template1)).toEqual(
|
||||
new Set(['template1', 'template2', 'template3', 'template4', 'template5']),
|
||||
);
|
||||
expect(new Set(depsMap.template2)).toEqual(new Set(['template2', 'template3', 'template4']));
|
||||
expect(new Set(depsMap.template3)).toEqual(new Set(['template3', 'template4']));
|
||||
expect(new Set(depsMap.template2)).toEqual(new Set(['template2', 'template3', 'template4', 'template5']));
|
||||
expect(new Set(depsMap.template3)).toEqual(new Set(['template3', 'template4', 'template5']));
|
||||
expect(new Set(depsMap.template4)).toEqual(new Set(['template4']));
|
||||
});
|
||||
|
||||
|
||||
@@ -1,33 +1,14 @@
|
||||
import { DivContainer, DivText, rewriteNames, template } from '../../src';
|
||||
|
||||
describe('Rewrite templates', () => {
|
||||
it('should shoud preserve home:block', () => {
|
||||
const rename = (name: string): string => `${name}/test`;
|
||||
let templates = {
|
||||
block1: new DivContainer({
|
||||
items: [template('block2'), template('block3')],
|
||||
}),
|
||||
block2: new DivContainer({
|
||||
items: [
|
||||
new DivText({
|
||||
text: 'text1',
|
||||
}),
|
||||
],
|
||||
}),
|
||||
block3: template('block2'),
|
||||
block4: template('home:block'),
|
||||
};
|
||||
|
||||
templates = rewriteNames(templates, rename).templates;
|
||||
expect(templates).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should validate template dependencies', () => {
|
||||
const templates = {
|
||||
template1: template('a', {
|
||||
items: [template('template2'), template('b')],
|
||||
}),
|
||||
template2: template('home:block'),
|
||||
template2: new DivText({
|
||||
text: 'template2',
|
||||
}),
|
||||
};
|
||||
expect(() => rewriteNames(templates, (x) => x)).toThrowError(
|
||||
`template 'template1' unsolvable dependencies: 'a','b'`,
|
||||
|
||||
@@ -53,7 +53,9 @@ describe('template helper version', () => {
|
||||
template3: new DivContainer({
|
||||
items: [template('template4'), template('template1')],
|
||||
}),
|
||||
template4: template('home:block'),
|
||||
template4: new DivText({
|
||||
text: 'template4',
|
||||
}),
|
||||
};
|
||||
|
||||
templates = rewriteTemplateVersions(templates).templates;
|
||||
|
||||
Reference in New Issue
Block a user