"use strict";
MetacatUI.recaptchaURL =
"https://www.google.com/recaptcha/api/js/recaptcha_ajax";
if (MetacatUI.mapKey) {
var gmapsURL =
"https://maps.googleapis.com/maps/api/js?v=3&libraries=places&key=" +
MetacatUI.mapKey;
define("gmaps", ["async!" + gmapsURL], function () {
return google.maps;
});
} else {
define("gmaps", null);
}
MetacatUI.d3URL = "../components/d3.v3.min";
/* Configure the app to use requirejs, and map dependency aliases to their
directory location (.js is ommitted). Shim libraries that don't natively
support requirejs. */
require.config({
baseUrl: MetacatUI.root + "/js/",
waitSeconds: 180, //wait 3 minutes before throwing a timeout error
map: MetacatUI.themeMap,
urlArgs:
"v=" + (MetacatUI.AppConfig.cachebuster || MetacatUI.metacatUIVersion),
paths: {
jquery: MetacatUI.root + "/components/jquery-1.9.1.min",
jqueryui: MetacatUI.root + "/components/jquery-ui.min",
jqueryform: MetacatUI.root + "/components/jquery.form",
underscore: MetacatUI.root + "/components/underscore-min",
backbone: MetacatUI.root + "/components/backbone-min",
localforage: MetacatUI.root + "/components/localforage.min",
bootstrap: MetacatUI.root + "/components/bootstrap.min",
text: MetacatUI.root + "/components/require-text",
jws: MetacatUI.root + "/components/jws-3.2.min",
jsrasign: MetacatUI.root + "/components/jsrsasign-4.9.0.min",
async: MetacatUI.root + "/components/async",
recaptcha: [MetacatUI.recaptchaURL, "scripts/placeholder"],
nGeohash: MetacatUI.root + "/components/geohash/main",
fancybox: MetacatUI.root + "/components/fancybox/jquery.fancybox.pack", //v. 2.1.5
annotator: MetacatUI.root + "/components/annotator/v1.2.10/annotator-full",
bioportal: MetacatUI.root + "/components/bioportal/jquery.ncbo.tree-2.0.2",
clipboard: MetacatUI.root + "/components/clipboard.min",
uuid: MetacatUI.root + "/components/uuid",
md5: MetacatUI.root + "/components/md5",
rdflib: MetacatUI.root + "/components/rdflib.min",
x2js: MetacatUI.root + "/components/xml2json",
he: MetacatUI.root + "/components/he",
citation: MetacatUI.root + "/components/citation.min",
promise: MetacatUI.root + "/components/es6-promise.min",
metacatuiConnectors: MetacatUI.root + "/js/connectors/Filters-Search",
// showdown + extensions (used in the MarkdownView to convert markdown to html)
showdown: MetacatUI.root + "/components/showdown/showdown.min",
showdownHighlight:
MetacatUI.root +
"/components/showdown/extensions/showdown-highlight/showdown-highlight",
highlight:
MetacatUI.root +
"/components/showdown/extensions/showdown-highlight/highlight.pack",
showdownFootnotes:
MetacatUI.root + "/components/showdown/extensions/showdown-footnotes",
showdownBootstrap:
MetacatUI.root + "/components/showdown/extensions/showdown-bootstrap",
showdownDocbook:
MetacatUI.root + "/components/showdown/extensions/showdown-docbook",
showdownKatex:
MetacatUI.root +
"/components/showdown/extensions/showdown-katex/showdown-katex.min",
showdownCitation:
MetacatUI.root +
"/components/showdown/extensions/showdown-citation/showdown-citation",
showdownImages:
MetacatUI.root + "/components/showdown/extensions/showdown-images",
showdownXssFilter:
MetacatUI.root +
"/components/showdown/extensions/showdown-xss-filter/showdown-xss-filter",
xss:
MetacatUI.root +
"/components/showdown/extensions/showdown-xss-filter/xss.min",
showdownHtags:
MetacatUI.root + "/components/showdown/extensions/showdown-htags",
// woofmark - markdown editor
woofmark: MetacatUI.root + "/components/woofmark.min",
// drop zone creates drag and drop areas
Dropzone: MetacatUI.root + "/components/dropzone-amd-module",
// Packages that convert between json data to markdown table
markdownTableFromJson:
MetacatUI.root + "/components/markdown-table-from-json.min",
markdownTableToJson: MetacatUI.root + "/components/markdown-table-to-json",
// Polyfill required for using dropzone with older browsers
corejs: MetacatUI.root + "/components/core-js",
// Searchable multi-select dropdown component
semanticUItransition:
MetacatUI.root + "/components/semanticUI/transition.min",
semanticUIdropdown: MetacatUI.root + "/components/semanticUI/dropdown.min",
// To make elements drag and drop, sortable
sortable: MetacatUI.root + "/components/sortable.min",
//Cesium
cesium:
"https://cesium.com/downloads/cesiumjs/releases/1.91/Build/Cesium/Cesium",
//Have a null fallback for our d3 components for browsers that don't support SVG
d3: MetacatUI.d3URL,
LineChart: ["views/LineChartView", null],
BarChart: ["views/BarChartView", null],
CircleBadge: ["views/CircleBadgeView", null],
DonutChart: ["views/DonutChartView", null],
MetricsChart: ["views/MetricsChartView", null],
},
shim: {
/* used for libraries without native AMD support */
underscore: {
exports: "_",
},
backbone: {
deps: ["underscore", "jquery"],
exports: "Backbone",
},
bootstrap: {
deps: ["jquery"],
exports: "Bootstrap",
},
annotator: {
exports: "Annotator",
},
bioportal: {
exports: "Bioportal",
},
jws: {
exports: "JWS",
deps: ["jsrasign"],
},
nGeohash: {
exports: "geohash",
},
fancybox: {
deps: ["jquery"],
},
uuid: {
exports: "uuid",
},
rdflib: {
exports: "rdf",
},
xss: {
exports: "filterXSS",
},
citation: {
exports: "citationRequire",
},
promise: {
exports: "Promise",
},
metacatuiConnectors: {
exports: "FiltersSearchConnector",
},
},
});
MetacatUI.appModel = MetacatUI.appModel || {};
MetacatUI.appView = MetacatUI.appView || {};
MetacatUI.uiRouter = MetacatUI.uiRouter || {};
MetacatUI.appSearchResults = MetacatUI.appSearchResults || {};
MetacatUI.appSearchModel = MetacatUI.appSearchModel || {};
/**
* @name MetacatUI.rootDataPackage
* @type {string}
* @description The top-level {@link DataPackage} that is currently being viewed or edited in MetacatUI.
*/
MetacatUI.rootDataPackage = MetacatUI.rootDataPackage || {};
MetacatUI.statsModel = MetacatUI.statsModel || {};
MetacatUI.mapModel = MetacatUI.mapModel || {};
MetacatUI.appLookupModel = MetacatUI.appLookupModel || {};
MetacatUI.nodeModel = MetacatUI.nodeModel || {};
MetacatUI.appUserModel = MetacatUI.appUserModel || {};
MetacatUI.analytics = MetacatUI.analytics || {};
/* Setup the application scaffolding first */
require(["bootstrap", "views/AppView", "models/AppModel"], function (
Bootstrap,
AppView,
AppModel,
) {
"use strict";
// Create an AppModel, which controls the global app configuration and app states
// To be compatible with MetacatUI 2.11.X and earlier, we need to set the metacat context attribute here.
// This supports the old way tof configuring the app via the index.html file.
// As of MetacatUI 2.12.0, it is recommended that you configure MetacatUI via an AppConfig file.
MetacatUI.appModel = new AppModel({
context: MetacatUI.AppConfig.metacatContext,
});
//Check for custom settings in the theme config file
if (typeof MetacatUI.customAppConfig == "function")
MetacatUI.customAppConfig();
/* Now require the rest of the libraries for the application */
require([
"underscore",
"backbone",
"routers/router",
"collections/SolrResults",
"models/Search",
"models/Stats",
"models/Map",
"models/LookupModel",
"models/NodeModel",
"models/UserModel",
"models/DataONEObject",
"collections/DataPackage",
], function (
_,
Backbone,
UIRouter,
SolrResultList,
Search,
Stats,
MapModel,
LookupModel,
NodeModel,
UserModel,
DataONEObject,
DataPackage,
) {
"use strict";
//Create all the other models and collections first
MetacatUI.appSearchResults = new SolrResultList([], {});
MetacatUI.appSearchModel = new Search();
MetacatUI.statsModel = new Stats();
MetacatUI.mapModel =
typeof customMapModelOptions == "object"
? new MapModel(customMapModelOptions)
: new MapModel();
MetacatUI.appLookupModel = new LookupModel();
MetacatUI.nodeModel = new NodeModel();
MetacatUI.appUserModel = new UserModel();
require(["models/analytics/GoogleAnalytics"], function (Analytics) {
MetacatUI.analytics = new Analytics();
});
/* Create a general event dispatcher to enable
communication across app components
*/
MetacatUI.eventDispatcher = _.clone(Backbone.Events);
//Load the App View now
MetacatUI.appView = new AppView();
MetacatUI.appView.render();
// Initialize routing and start Backbone.history()
(function () {
/**
* Backbone.routeNotFound
*
* Simple plugin that listens for false returns on Backbone.history.loadURL and fires an event
* to let the application know that no routes matched.
*
* @author STRML
*/
var oldLoadUrl = Backbone.History.prototype.loadUrl;
_.extend(Backbone.History.prototype, {
/*
* Override loadUrl & watch return value. Trigger event if no route was matched.
* @extends Backbone.History
* @return {Boolean} True if a route was matched
*/
loadUrl: function (fragment) {
if (!this.matchRoot()) return false;
fragment = this.fragment = this.getFragment(fragment);
var match = _.some(this.handlers, function (handler) {
if (handler.route.test(fragment)) {
handler.callback(fragment);
return true;
}
});
if (!match) this.trigger("routeNotFound");
return match;
},
matchRoot: function () {
var path = this.decodeFragment(this.location.pathname);
var rootPath = path.slice(0, this.root.length - 1) + "/";
return rootPath === this.root;
},
decodeFragment: function (fragment) {
return decodeURI(fragment.replace(/%25/g, "%2525"));
},
});
}).call(this);
//Make the router and begin the Backbone history
//The router will figure out which view to load first based on window location
MetacatUI.uiRouter = new UIRouter();
//Take the protocol and origin out of the root URL when sending it to Backbone.history.
// The root URL sent to Backbone.history should be either `/` or `/directory/...`
var historyRoot = MetacatUI.root;
//If there is a protocol
if (historyRoot.indexOf("://") > -1) {
//Get the substring after the ``://``
historyRoot = historyRoot.substring(historyRoot.indexOf("://") + 3);
//If there is no `/`, this must be the root directory
if (historyRoot.indexOf("/") == -1) historyRoot = "/";
//Otherwise get the substring after the first /
else historyRoot = historyRoot.substring(historyRoot.indexOf("/"));
}
//If there are no colons, periods, or slashes, this is a directory name
else if (
historyRoot.indexOf(":") == -1 &&
historyRoot.indexOf(".") == -1 &&
historyRoot.indexOf("/") == -1
) {
//So the root is a leading slash and the directory name
historyRoot = "/" + historyRoot;
}
//If there is a slash, get the path name starting with the slash
else if (historyRoot.indexOf("/") > -1) {
historyRoot = historyRoot.substring(historyRoot.indexOf("/"));
}
//All other strings are the root directory
else {
historyRoot = "/";
}
Backbone.history.start({
pushState: true,
root: historyRoot,
});
$(document).on("click", "a:not([data-toggle],[target])", function (evt) {
// Don't hijack the event if the user had Control or Command held down
if (evt.ctrlKey || evt.metaKey) {
return;
}
var href = { prop: $(this).prop("href"), attr: $(this).attr("href") };
// Stop if the click happened on an a w/o an href
// This is kind of a weird edge case where. This could be removed if
// we remove these instances from the codebase
if (
typeof href === "undefined" ||
typeof href.attr === "undefined" ||
href.attr === ""
) {
return;
}
//Don't route to URLs with the DataONE API, which are sometimes proxied
// via Apache ProxyPass so start with the MetacatUI origin
if (
href.attr.indexOf("/cn/v2/") > 0 ||
href.attr.indexOf("/mn/v2/") > 0
) {
return;
}
var root =
location.protocol +
"//" +
location.host +
Backbone.history.options.root;
// Remove the MetacatUI (plus a trailing /) from the value in the 'href'
// attribute of the clicked element so Backbone.history.navigate works.
// Note that a RegExp was used here to anchor the .replace call to the
// front of the string so that this code works when MetacatUI.root is "".
var route = href.attr.replace(new RegExp("^" + MetacatUI.root + "/"), "");
// Catch routes hrefs that start with # and don't do anything with them
if (href.attr.indexOf("#") == 0) {
return;
}
//If the URL is not a route defined in the app router, then follow the link
//If the URL is not at the MetacatUI root, then follow the link
if (
href.prop &&
href.prop.slice(0, root.length) === root &&
_.contains(
MetacatUI.uiRouter.getRouteNames(),
MetacatUI.uiRouter.getRouteName(route),
)
) {
evt.preventDefault();
Backbone.history.navigate(route, true);
}
});
MetacatUI.appModel.trigger("appInitialized");
});
});