neweb
Version:
[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url] [![Coverage percentage][coveralls-image]][coveralls-url] [ • 4.66 kB
text/typescript
import { IPage, IPageFrame } from "..";
interface IReplacePageInfo {
page: IPage;
oldPage: IPage;
newFrames: IPageFrame[];
frames: IPageFrame[];
frameidsForRemoving: string[];
frameForChangeParams: Array<{
frameId: string;
params: any;
}>;
}
class PageComparator {
public getCompareInfo(oldPage: IPage, newPage: IPage) {
const replacePageInfo: IReplacePageInfo = {
page: newPage,
oldPage,
newFrames: [],
frameForChangeParams: [],
frameidsForRemoving: [],
frames: [],
};
const oldFramesByPaths = collectFramesByPath(oldPage);
const rootFrame = this.processFrame(
replacePageInfo, oldFramesByPaths, newPage, newPage.rootFrame, "_root");
const newFramesIds = replacePageInfo.frames.map((f) => f.frameId);
const oldFramesIds = oldPage.frames.map((f) => f.frameId);
replacePageInfo.frameidsForRemoving = oldFramesIds.filter((f) =>
newFramesIds.indexOf(f) === -1,
);
replacePageInfo.page = {
frames: replacePageInfo.frames,
modules: newPage.modules,
meta: newPage.meta,
title: newPage.title,
url: newPage.url,
rootFrame,
};
return replacePageInfo;
}
protected processFrame(
replacePageInfo: IReplacePageInfo,
oldFramesByPaths: { [index: string]: { frameId: string } },
newPage: IPage, frameId: string, pathName: string) {
const newFrame = getFrameById(newPage, frameId);
const framePath = pathName + "/$" + newFrame.frameName;
const oldFrameByPath = oldFramesByPaths[framePath];
if (oldFrameByPath) {
const oldFrame = getFrameById(replacePageInfo.oldPage, oldFrameByPath.frameId);
const childFrames: { [index: string]: string } = {};
if (JSON.stringify(oldFrame.params) !== JSON.stringify(newFrame.params)) {
replacePageInfo.frameForChangeParams.push({ frameId: oldFrame.frameId, params: newFrame.params });
}
Object.keys(newFrame.frames).map((placeName) => {
childFrames[placeName] = this.processFrame(
replacePageInfo, oldFramesByPaths, newPage, newFrame.frames[placeName], framePath + "/"
+ "_" + placeName);
});
const xFrame: IPageFrame = {
frameId: oldFrame.frameId,
frameName: newFrame.frameName,
data: newFrame.data,
frames: childFrames,
frameVersion: newFrame.frameVersion,
modules: newFrame.modules,
params: newFrame.params,
};
replacePageInfo.frames.push(xFrame);
return xFrame.frameId;
} else {
const childFrames: { [index: string]: string } = {};
Object.keys(newFrame.frames).map((placeName) => {
childFrames[placeName] = this.processFrame(
replacePageInfo, oldFramesByPaths, newPage, newFrame.frames[placeName], framePath + "/"
+ "_" + placeName);
});
const xFrame = { ...newFrame, frames: childFrames };
replacePageInfo.frames.push(xFrame);
replacePageInfo.newFrames.push(xFrame);
return xFrame.frameId;
}
}
}
export function collectFramesByPath(page: IPage): { [index: string]: { frameId: string } } {
const rootFrame = getFrameById(page, page.rootFrame);
const frames = collectFramesForFrame(page, rootFrame, "_root/$" + rootFrame.frameName);
return { ...frames, ["_root/$" + rootFrame.frameName]: { frameId: page.rootFrame } };
}
export function collectFramesForFrame(page: IPage, frame: IPageFrame, path: string) {
const frames: { [index: string]: { frameId: string } } = {};
Object.keys(frame.frames).map((placeName) => {
const childFrame = getFrameById(page, frame.frames[placeName]);
const childPath = path + "/_" + placeName + "/$" + childFrame.frameName;
frames[childPath] = { frameId: childFrame.frameId };
collectFramesForFrame(page, childFrame, childPath);
});
return frames;
}
export function getFrameById(page: IPage, frameId: string) {
const frame = page.frames.find((f) => f.frameId === frameId);
if (!frame) {
throw new Error("Not found frame " + frameId);
}
return frame;
}
export default PageComparator;