Commit 2ebe4120 authored by Boris Kocherov's avatar Boris Kocherov

fix memory leak

parent b49013f9
/*jslint nomen: true, maxlen: 200, indent: 2, maxerr: 100*/ /*jslint nomen: true, maxlen: 200, indent: 2, maxerr: 100*/
/*global window, document, URL, rJS, RSVP, jIO, tv4, location */ /*global window, document, URL, rJS, RSVP, jIO, tv4, Blob */
(function (window, document, location, rJS, RSVP, jIO, tv4) { (function (window, document, Blob, rJS, RSVP, jIO, tv4) {
"use strict"; "use strict";
var expandSchema; var expandSchema;
...@@ -11,6 +11,18 @@ ...@@ -11,6 +11,18 @@
}); });
} }
function getUrlWithoutHash(url) {
if (typeof url !== "string") {
url = url.href;
}
var index = url.indexOf('#');
if (index >= 0) {
return url.substring(0, index);
}
return url;
}
function URLwithJio(url, base_url) { function URLwithJio(url, base_url) {
var urn_prefix, var urn_prefix,
pathname, pathname,
...@@ -209,50 +221,44 @@ ...@@ -209,50 +221,44 @@
} }
function map_url(g, download_url) { function map_url(g, download_url) {
var mapped_url = download_url, var hash = download_url.hash,
hash = mapped_url.hash, mapped_url = getUrlWithoutHash(download_url),
i, i,
schemas = g.props.schemas, schemas = g.props.schemas,
next_mapped_url; next_mapped_url;
// simple defence forever loop // simple defence forever loop
for (i = 0; i < Object.keys(schemas).length; i += 1) { for (i = 0; i < Object.keys(schemas).length; i += 1) {
next_mapped_url = g.props.schemas[mapped_url.origin + mapped_url.pathname + mapped_url.search]; next_mapped_url = schemas[mapped_url];
if (next_mapped_url === undefined) { if (next_mapped_url === undefined) {
break; break;
} }
mapped_url = next_mapped_url; mapped_url = new URL(next_mapped_url, g.__path);
if (typeof mapped_url !== "string") {
mapped_url = resolveLocalReference(mapped_url, hash);
break;
}
mapped_url = new URL(mapped_url, g.__path);
if (hash[0] === '#') { if (hash[0] === '#') {
hash = hash.slice(1); hash = hash.slice(1);
} }
if (hash === '/') { if (hash === '/') {
hash = ''; hash = '';
} }
hash = mapped_url.hash + hash; hash = mapped_url.hash || "#" + hash;
mapped_url = getUrlWithoutHash(mapped_url);
} }
return mapped_url; return new URL(mapped_url + hash);
} }
function loadJSONSchema(g, $ref, path) { function loadJSONSchema(g, $ref, path) {
var protocol, var protocol,
abs_url,
url, url,
download_url, download_url,
hash, hash,
mapped_url,
queue; queue;
// XXX need use `id` property // XXX need use `id` property
if (!path) { if (!path) {
path = "/"; path = "/";
} }
url = convertUrlToAbsolute(g, path, decodeURI($ref), window.location); abs_url = convertUrlToAbsolute(g, path, decodeURI($ref), window.location);
mapped_url = map_url(g, url); url = map_url(g, abs_url);
if (mapped_url instanceof URL || mapped_url instanceof URLwithJio) { abs_url = abs_url.href;
url = mapped_url;
}
protocol = url.protocol; protocol = url.protocol;
if (protocol === "http:") { if (protocol === "http:") {
if (window.location.protocol !== protocol) { if (window.location.protocol !== protocol) {
...@@ -261,35 +267,27 @@ ...@@ -261,35 +267,27 @@
// throw new Error("You cannot mixed http and https calls"); // throw new Error("You cannot mixed http and https calls");
} }
} }
download_url = url.origin + url.pathname + url.search; download_url = getUrlWithoutHash(url);
hash = url.hash; hash = url.hash;
url = url.href; url = url.href;
if (!(mapped_url instanceof URL || mapped_url instanceof URLwithJio)) { if (download_url.startsWith("urn:jio:")) {
queue = RSVP.Queue() queue = RSVP.Queue()
.push(function () { .push(function () {
return mapped_url; return g.resolveExternalReference(download_url);
}); });
} else { } else {
if (download_url.startsWith("urn:jio:")) { queue = RSVP.Queue()
queue = RSVP.Queue() .push(function () {
.push(function () { return downloadJSON(download_url);
return g.resolveExternalReference(download_url);
});
} else {
queue = RSVP.Queue()
.push(function () {
return downloadJSON(download_url);
});
}
queue
.push(function (json) {
if (checkHardCircular(g, path, url)) {
throw new Error("Circular reference detected");
}
return resolveLocalReference(json, hash);
}); });
} }
return queue return queue
.push(function (json) {
if (checkHardCircular(g, path, url)) {
throw new Error("Circular reference detected");
}
return resolveLocalReference(json, hash);
})
.push(undefined, function (err) { .push(undefined, function (err) {
// XXX it will be great to have ability convert json_pointers(hash) // XXX it will be great to have ability convert json_pointers(hash)
// in line numbers for pointed to line in rich editors. // in line numbers for pointed to line in rich editors.
...@@ -322,7 +320,9 @@ ...@@ -322,7 +320,9 @@
} else { } else {
// save map url only for correctly resolved schema // save map url only for correctly resolved schema
// otherwise we have issue in convertToRealWorldSchemaPath // otherwise we have issue in convertToRealWorldSchemaPath
g.props.schema_map[path] = url; if (!g.props.hasOwnProperty(path)) {
g.props.schema_map[path] = abs_url;
}
} }
schemaPushSchemaPart(g.props.schema, path, JSON.parse(JSON.stringify(schema_part))); schemaPushSchemaPart(g.props.schema, path, JSON.parse(JSON.stringify(schema_part)));
// console.log(g.props.schema[""]); // console.log(g.props.schema[""]);
...@@ -602,7 +602,9 @@ ...@@ -602,7 +602,9 @@
mapped_url = convertUrlToAbsolute(g, schema_path, '#' + schema_path, window.location); mapped_url = convertUrlToAbsolute(g, schema_path, '#' + schema_path, window.location);
// XXX /? // XXX /?
mapped_url = mapped_url + 'definitions/' + key; mapped_url = mapped_url + 'definitions/' + key;
g.props.schemas[url] = mapped_url; if (!g.props.schemas.hasOwnProperty(url)) {
g.props.schemas[url] = mapped_url;
}
} }
} }
} }
...@@ -790,7 +792,11 @@ ...@@ -790,7 +792,11 @@
z.key = options.key; z.key = options.key;
} }
if (options.hasOwnProperty("schema")) { if (options.hasOwnProperty("schema")) {
z.schema = JSON.stringify(options.schema); if (typeof options.schema === "string") {
z.schema = options.schema;
} else {
z.schema = JSON.stringify(options.schema);
}
} }
if (options.hasOwnProperty("schema_url")) { if (options.hasOwnProperty("schema_url")) {
z.schema_url = options.schema_url; z.schema_url = options.schema_url;
...@@ -862,7 +868,8 @@ ...@@ -862,7 +868,8 @@
window.location.toString(); window.location.toString();
g.props.schema[""] = schema; g.props.schema[""] = schema;
g.props.schema_map["/"] = schema_url; g.props.schema_map["/"] = schema_url;
g.props.schemas[schema_url] = schema; g.props.schemas[schema_url] = URL
.createObjectURL(new Blob([g.state.schema], {type : 'application/json'}));
queue = expandSchemaForField(g, schema, "/", true); queue = expandSchemaForField(g, schema, "/", true);
} else { } else {
schema_url = g.state.schema_url || schema_url = g.state.schema_url ||
...@@ -936,4 +943,4 @@ ...@@ -936,4 +943,4 @@
return {}; return {};
}, {mutex: 'changestate'}); }, {mutex: 'changestate'});
}(window, document, location, rJS, RSVP, jIO, tv4)); }(window, document, Blob, rJS, RSVP, jIO, tv4));
\ No newline at end of file \ No newline at end of file
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