blob: ea055ba6d390f7d8c90e4acef5796c92992bcf38 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function () {
'use strict';
// ======================================================================================
// = Browser Hooker =
// ======================================================================================
var is_chrome = navigator.userAgent.indexOf('Chrome') > -1;
var is_explorer = navigator.userAgent.indexOf('MSIE') > -1;
var is_firefox = navigator.userAgent.indexOf('Firefox') > -1;
var is_safari = navigator.userAgent.indexOf("Safari") > -1;
var is_opera = navigator.userAgent.toLowerCase().indexOf("op") > -1;
if(is_chrome && is_safari) is_safari = false;
if(is_chrome && is_opera) is_chrome = false;
if(is_safari) {
$("body").addClass("safari");
}
// ======================================================================================
// = Host =
// ======================================================================================
var _host = "";
var _app = {};
if(localStorage) {
_host = localStorage.getItem("host") || "";
_app = common.parseJSON(localStorage.getItem("app"), {});
}
window._host = function (host) {
if(host) {
_host = host.replace(/[\\\/]+$/, "");
if(localStorage) {
localStorage.setItem("host", _host);
}
}
return _host;
};
window._app = function (appName, viewPath) {
if(arguments.length) {
_app[appName] = {
viewPath: viewPath
};
if(localStorage) {
localStorage.setItem("app", JSON.stringify(_app));
}
}
return _app;
};
window._app.clear = function () {
if(localStorage) {
_app = {};
localStorage.removeItem("app");
}
};
// ======================================================================================
// = Register =
// ======================================================================================
var _moduleStateId = 0;
var _registerAppList = [];
var _lastRegisterApp = null;
var _hookRequireFunc = null;
function Module(dependencies) {
this.dependencies = dependencies;
this.queueList = [];
this.routeList = [];
this.portalList = [];
this.widgetList = [];
this.requireRest = 0;
this.requireDeferred = null;
return this;
}
// GRUNT REPLACEMENT: Module.buildTimestamp = TIMESTAMP
window._TRS = function() {
return Module.buildTimestamp || Math.random();
};
Module.prototype.service = function () {
this.queueList.push({type: "service", args: arguments});
return this;
};
Module.prototype.directive = function () {
this.queueList.push({type: "directive", args: arguments});
return this;
};
Module.prototype.controller = function () {
this.queueList.push({type: "controller", args: arguments});
return this;
};
/**
* Add portal into side navigation bar.
* @param {{}} portal Config portal content
* @param {string} portal.name Display name
* @param {string} portal.icon Display icon. Use 'FontAwesome'
* @param {string=} portal.path Route path
* @param {[]=} portal.list Sub portal
* @param {boolean} isSite true will show in site page or will shown in main page
*/
Module.prototype.portal = function (portal, isSite) {
this.portalList.push({portal: portal, isSite: isSite});
return this;
};
/**
* Set application route
* @param {{}|string=} state Config state. More info please check angular ui router
* @param {{}} config Route config
* @param {string} config.url Root url. start with '/'
* @param {string} config.templateUrl Template url. Relative path of application `viewPath`
* @param {string} config.controller Set page controller
*/
Module.prototype.route = function (state, config) {
if(arguments.length === 1) {
config = state;
state = "_APPLICATION_STATE_" + _moduleStateId++;
}
if(!config.url) throw "Url not defined!";
this.routeList.push({
state: state,
config: config
});
return this;
};
/**
* Register home page widget
* @param {string} name Widget name
* @param {Function} renderFunc Register function
* @param {boolean} isSite true will show in site page or will shown in main page
*/
Module.prototype.widget = function (name, renderFunc, isSite) {
this.widgetList.push({
widget: {
name: name,
renderFunc: renderFunc
},
isSite: isSite
});
return this;
};
Module.prototype.require = function (scriptURL) {
var _this = this;
_this.requireRest += 1;
if(!_this.requireDeferred) {
_this.requireDeferred = $.Deferred();
}
setTimeout(function () {
$.getScript(_this.baseURL + "/" + scriptURL).then(function () {
if(_hookRequireFunc) {
_hookRequireFunc(_this);
} else {
console.error("Hook function not set!", _this);
}
}).always(function () {
_hookRequireFunc = null;
_this.requireRest -= 1;
_this.requireCheck();
});
}, 0);
};
Module.prototype.requireCSS = function (styleURL) {
var _this = this;
setTimeout(function () {
$("<link/>", {
rel: "stylesheet",
type: "text/css",
href: _this.baseURL + "/" + styleURL + "?_=" + _TRS()
}).appendTo("head");
}, 0);
};
Module.prototype.requireCheck = function () {
if(this.requireRest === 0) {
this.requireDeferred.resolve();
}
};
/**
* Get module instance. Will init angular module.
* @param {string} moduleName angular module name
*/
Module.prototype.getInstance = function (moduleName) {
var _this = this;
var deferred = $.Deferred();
var module = angular.module(moduleName, this.dependencies);
// Required list
$.when(this.requireDeferred).always(function () {
// Fill module props
$.each(_this.queueList, function (i, item) {
var type = item.type;
var args = Array.prototype.slice.apply(item.args);
if (type === "controller") {
args[0] = moduleName + "_" + args[0];
}
module[type].apply(module, args);
});
// Render routes
var routeList = $.map(_this.routeList, function (route) {
var config = route.config = $.extend({}, route.config);
// Parse url
if(config.site) {
config.url = "/site/:siteId/" + config.url.replace(/^[\\\/]/, "");
}
// Parse template url
var parser = document.createElement('a');
parser.href = _this.baseURL + "/" + config.templateUrl;
parser.search = parser.search ? parser.search + "&_=" + window._TRS() : "?_=" + window._TRS();
config.templateUrl = parser.href;
if (typeof config.controller === "string") {
config.controller = moduleName + "_" + config.controller;
}
return route;
});
// Portal update
$.each(_this.portalList, function (i, config) {
config.portal.application = moduleName;
});
// Widget update
$.each(_this.widgetList, function (i, config) {
config.widget.application = moduleName;
});
deferred.resolve({
application: moduleName,
portalList: _this.portalList,
routeList: routeList,
widgetList: _this.widgetList
});
});
return deferred;
};
window.register = function (dependencies) {
if($.isArray(dependencies)) {
_lastRegisterApp = new Module(dependencies);
} else if(typeof dependencies === "function") {
_hookRequireFunc = function (module) {
dependencies(module);
};
}
return _lastRegisterApp;
};
// ======================================================================================
// = Main =
// ======================================================================================
$(function () {
console.info("[Eagle] Application initialization...");
// Load providers
$.get(_host + "/rest/apps/providers").then(function (res) {
/**
* @param {{}} oriApp application provider
* @param {string} oriApp.viewPath path of application interface
*/
var promiseList = $.map(res.data || [], function (oriApp) {
var deferred = $.Deferred();
var viewPath = common.getValueByPath(_app, [oriApp.type, "viewPath"], oriApp.viewPath);
if(viewPath) {
var url = viewPath;
url = url.replace(/^[\\\/]/, "").replace(/[\\\/]$/, "");
$.getScript(url + "/index.js").then(function () {
if(_lastRegisterApp) {
_registerAppList.push(oriApp.type);
_lastRegisterApp.baseURL = url;
_lastRegisterApp.getInstance(oriApp.type).then(function (module) {
deferred.resolve(module);
});
} else {
console.error("Application not register:", oriApp.type);
deferred.resolve();
}
}, function () {
console.error("Load application failed:", oriApp.type, viewPath);
deferred.resolve();
}).always(function () {
_lastRegisterApp = null;
});
} else {
deferred.resolve();
}
return deferred;
});
common.deferred.all(promiseList).then(function (moduleList) {
// Filter module list
moduleList = $.map(moduleList, function (module) {
return module;
});
var routeList = $.map(moduleList, function (module) {
return module.routeList;
});
var portalList = $.map(moduleList, function (module) {
return module.portalList;
});
var widgetList = $.map(moduleList, function (module) {
return module.widgetList;
});
$(document).trigger("APPLICATION_READY", {
appList: _registerAppList,
moduleList: moduleList,
routeList: routeList,
portalList: portalList,
widgetList: widgetList
});
});
});
});
})();