Commit 276a76ab authored by Laurent Wouters's avatar Laurent Wouters
Browse files

Fixed issue cweb #10129176 Factoriser le téléchargement de la définition des vues

parent ca04025c18b3
......@@ -240,7 +240,6 @@ export class ViewRegistry {
constructor() {
this.sources = [];
this.descriptors = {};
this.cache = {};
}
/**
* The sources for this registry
......@@ -250,10 +249,6 @@ export class ViewRegistry {
* The registry of descriptors
*/
descriptors: ViewDescriptors;
/**
* The cache for the fetched remote resources
*/
cache: { [uri: string]: string };
}
/**
......@@ -268,38 +263,27 @@ export function loadRegistry(registry: ViewRegistry): Promise<ViewRegistry> {
) => {
registry.descriptors = {};
loadDescriptors(registry.sources).then((descriptors: ViewDescriptors) => {
let descriptorsArray = Object.getOwnPropertyNames(descriptors).map(
(name: string) => descriptors[name]
);
let remaining = descriptorsArray.length;
function onFinishedPart() {
remaining -= 1;
if (remaining == 0) {
resolve(registry);
}
}
for (var i = 0; i != descriptorsArray.length; i++) {
resolveResourcesOf(registry, descriptorsArray[i])
.then((descriptor: ViewDescriptor) => {
registry.descriptors[descriptor.identifier] = descriptor;
onFinishedPart();
})
.catch((reason: any) => {
// cannot happen, do nothing
});
}
registry.descriptors = descriptors;
resolve(registry);
});
}
);
}
/**
* Represents a cache of content for view resources
*/
export interface ViewResourceCache {
[uri: string]: string;
}
/**
* Gets the content of a resource
* @param registry The current registry
* @param cache The cache to use
* @param resource The resource
*/
function getResourceContent(
registry: ViewRegistry,
export function getResourceContent(
cache: ViewResourceCache,
resource: ViewResource
): Promise<string> {
return new Promise<string>(
......@@ -308,8 +292,8 @@ function getResourceContent(
resolve((resource as ViewResourceInline).content);
} else if (resource.location == ViewResourceLocation.remote) {
let uri = (resource as ViewResourceRemote).uri;
if (registry.cache.hasOwnProperty(uri)) {
resolve(registry.cache[uri]);
if (cache.hasOwnProperty(uri)) {
resolve(cache[uri]);
return;
}
let xmlHttp = new XMLHttpRequest();
......@@ -319,7 +303,7 @@ function getResourceContent(
reject("HTTP error: " + xmlHttp.status);
return;
}
registry.cache[uri] = xmlHttp.responseText;
cache[uri] = xmlHttp.responseText;
resolve(xmlHttp.responseText);
}
};
......@@ -337,99 +321,3 @@ function getResourceContent(
}
);
}
/**
* Resolves the content of all the resources in a view descriptor
* @param registry The current registry
* @param descriptor The descriptor
*/
function resolveResourcesOf(
registry: ViewRegistry,
descriptor: ViewDescriptor
): Promise<ViewDescriptor> {
return new Promise<ViewDescriptor>(
(
resolve: (result: ViewDescriptor) => void,
reject: (reason: any) => void
) => {
let remaining =
descriptor.resourceMain.location == ViewResourceLocation.remote ? 1 : 0;
let result: ViewDescriptor = {
identifier: descriptor.identifier,
name: descriptor.name,
description: descriptor.description,
entrypoint: descriptor.entrypoint,
resourceCss: descriptor.resourceCss.map((resource: ViewResource) => {
if (resource.location == ViewResourceLocation.remote) {
remaining += 1;
return null;
}
return resource;
}),
resourceJs: descriptor.resourceJs.map((resource: ViewResource) => {
if (resource.location == ViewResourceLocation.remote) {
remaining += 1;
return null;
}
return resource;
}),
resourceMain:
descriptor.resourceMain.location == ViewResourceLocation.remote
? null
: descriptor.resourceMain
};
if (remaining == 0) {
resolve(result);
return;
}
function onFinishedPart() {
remaining -= 1;
if (remaining == 0) {
resolve(result);
}
}
function getContent(
resource: ViewResource,
setter: (resource: ViewResource) => void
) {
getResourceContent(registry, resource)
.then((content: string) => {
let resolved: ViewResourceInline = {
location: ViewResourceLocation.inline,
content: content
};
setter(resolved);
onFinishedPart();
})
.catch((reason: any) => {
console.log(reason);
let resolved: ViewResourceInline = {
location: ViewResourceLocation.inline,
content: ""
};
setter(resolved);
onFinishedPart();
});
}
if (descriptor.resourceMain.location == ViewResourceLocation.remote) {
getContent(descriptor.resourceMain, (resource: ViewResource) => {
result.resourceMain = resource;
});
}
for (var i = 0; i != result.resourceCss.length; i++) {
if (result.resourceCss[i] == null) {
getContent(descriptor.resourceCss[i], (resource: ViewResource) => {
result.resourceCss[i] = resource;
});
}
}
for (var i = 0; i != result.resourceJs.length; i++) {
if (result.resourceJs[i] == null) {
getContent(descriptor.resourceJs[i], (resource: ViewResource) => {
result.resourceJs[i] = resource;
});
}
}
}
);
}
......@@ -20,7 +20,12 @@
import { RdfStore } from "rdflib";
import { ViewRenderer, Application, ViewRendering } from "./application";
import { ViewDescriptor, ViewRegistry, ViewResourceInline } from "./view-def";
import {
ViewDescriptor,
ViewRegistry,
ViewResourceCache,
getResourceContent
} from "./view-def";
/**
* The implementation of a view
......@@ -74,9 +79,11 @@ export function registerImplementation(implementation: ViewImplementation) {
/**
* Fetches the implementation corresponding to a descriptor
* @param cache The cache to use for remote content
* @param descriptor The descriptor
*/
function fetchImplementation(
cache: ViewResourceCache,
descriptor: ViewDescriptor
): Promise<ViewImplementation> {
return new Promise(
......@@ -84,39 +91,52 @@ function fetchImplementation(
resolve: (impl: ViewImplementation) => any,
reject: (reason: string) => void
) => {
let EMBEDDED = IMPL_EMBEDDED;
let result = eval(
(descriptor.resourceMain as ViewResourceInline).content
);
if (result == null || result == undefined) {
reject(
"Failed to load definition of " +
descriptor.name +
": Cannot find entrypoint"
);
return;
}
if (descriptor.entrypoint != null && descriptor.entrypoint.length > 0) {
result = result[descriptor.entrypoint];
}
if (result == null || result == undefined) {
reject(
"Failed to load definition of " +
descriptor.name +
": Cannot find entrypoint"
);
} else {
resolve(result);
}
getResourceContent(cache, descriptor.resourceMain)
.then((content: string) => {
let EMBEDDED = IMPL_EMBEDDED;
let result = eval(content);
if (result == null || result == undefined) {
reject(
"Failed to load definition of " +
descriptor.name +
": Cannot find entrypoint"
);
return;
}
if (
descriptor.entrypoint != null &&
descriptor.entrypoint.length > 0
) {
result = result[descriptor.entrypoint];
}
if (result == null || result == undefined) {
reject(
"Failed to load definition of " +
descriptor.name +
": Cannot find entrypoint"
);
} else {
resolve(result);
}
})
.catch((reason: string) => {
reject(
"Failed to fetch definition of " +
descriptor.name +
": Cannot find entrypoint"
);
});
}
);
}
/**
* Loads all implementations for the registered views
* @param cache The cache to use for remote content
* @param registry The registry to load
*/
function loadImplementations(
cache: ViewResourceCache,
registry: ViewRegistry
): Promise<ViewImplementations> {
return new Promise<ViewImplementations>(
......@@ -133,7 +153,7 @@ function loadImplementations(
}
Object.keys(registry.descriptors).map((id: string) => {
let descriptor = registry.descriptors[id];
fetchImplementation(descriptor)
fetchImplementation(cache, descriptor)
.then((implementation: ViewImplementation) => {
implementations[id] = implementation;
onPartFinished();
......@@ -265,11 +285,13 @@ class ViewRendererImpl implements ViewRenderer {
* Creates a new view renderer
* @param application The current application
* @param registry The view registry to use
* @param cache The cache to use for remote content
* @param forceView Forces the selection of a specific view
*/
export function newRenderer(
application: Application,
registry: ViewRegistry,
cache: ViewResourceCache,
forceView: string = null
): Promise<ViewRenderer> {
return new Promise<ViewRenderer>(
......@@ -277,15 +299,17 @@ export function newRenderer(
resolve: (renderer: ViewRenderer) => void,
reject: (reason: any) => void
) => {
loadImplementations(registry).then((impls: ViewImplementations) => {
let renderer = new ViewRendererImpl(
application,
registry,
impls,
forceView
);
resolve(renderer);
});
loadImplementations(cache, registry).then(
(impls: ViewImplementations) => {
let renderer = new ViewRendererImpl(
application,
registry,
impls,
forceView
);
resolve(renderer);
}
);
}
);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment