123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 |
- $.define(["jQuery", "util", "doc", "win", "body"], "spa", function($, util, doc, win, body) {
- var head = doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement,
- baseElement = head.getElementsByTagName("base")[0],
- ahref = { an: "href", av: "javascript:;" },
- spa_modal_index = 0,
- spa_css_ref = 0,
- resCache = {},
- cssCache = {},
- htmlCache = { "#": "#" },
- modelCache = {"_def_error_form":{}},
- scriptCache = {}, resUri, menuUri, menuEle,
- main, mainEle,
- cfg = {
- ajaxCfg: { mask: true },
- mask: true,
- loadEnabled: true
- },
- load_res = function() {
- if(resUri) {
- util.get(resUri, null, function(data) {
-
- * res =[{id:"",uri:"",css:"",script:""},{id:"",uri:"",css:"",script:""},...........]
- */
- if(data && data.length) {
- data.forEach(function(item) {
- resCache[item.id] = item;
- });
- }
- menuUri ? load_menu() : showMain();
- },false, cfg.ajaxCfg);
- }
- },
- load_menu = function() {
- util.get(menuUri, null, function(menu) {
- build_menu(menu);
- showMain();
- },false, cfg.ajaxCfg);
- },
- build_menu = function(menu) {
- if(menuEle && menuEle.length && menu && menu.length) {
- var ul = { tn: "ul", attrs: [{ an: "class", av: "nav nav-root" }], chs: [] };
- build_menu_item(ul.chs, menu);
- menuEle.empty();
- util.appendChild(menuEle[0], ul);
- menuEle.find(".nav-hand").on("click", function(e) {
- var $this = $(this);
- menuEle.find(".nav-hand.active").removeClass("active");
- $this.addClass("active");
- if($this.hasClass("spa-modal")) {
- showModal($this.attr("res"));
- } else {
- location.hash = "#" + $this.attr("res");
- showMain();
- }
- });
- menuEle.find(".nav-branch-hand").on("click", function(e) {
- var prt = $(this).parent();
- if(prt.hasClass("open")) {
- prt.removeClass("open");
- } else {
- prt.parent().children(".open").removeClass("open");
- prt.addClass("open");
- }
- });
- }
- },
- build_menu_item = function(po, items) {
- var item, res, caption, iconClass;
- items.forEach(function(item) {
- var li = { tn: "li" },
- attrs = li.attrs = [],
- chses = li.chs = [],
- lia = { tn: "a", attrs: [ahref], chs: [] };
- chses.push(lia);
- var ic = "icon-" + (item.icon || (item.res ? "book" : "branch"));
- lia.chs.push({ tn: "i", attrs: [{ an: "class", av: ic }] });
- lia.chs.push(item.caption);
- var lac = "";
- if(item.res) {
- lia.attrs.push({ an: "res", av: item.res });
- lac = lac + (item.modal ? " nav-hand spa-modal" : " nav-hand");
- lia.attrs.push({ an: "class", av: lac })
- } else {
- lia.chs.push({ tn: "i", attrs: [{ an: "class", av: "icon fold" }] });
- lac = lac + " nav-branch-hand";
- attrs.push({ an: "class", av: "nav-parent" });
- var ul = { tn: "ul", attrs: [{ an: "class", av: "nav" }], chs: [] };
- chses.push(ul);
- build_menu_item(ul.chs, item.children);
- }
- lia.attrs.push({ an: "class", av: lac });
- po.push(li);
- });
- },
- loadModelCss = function(model) {
- if(model.css) {
- var uri = model.css;
- if(cssCache[uri]) {
- cssCache[uri]['ref'] = cssCache[uri]['ref'] + 1;
- } else {
- ++spa_css_ref;
- var css_id = "___spa_css_id_" + spa_css_ref;
- cssCache[uri] = { ref: 1, id: css_id };
- var link = doc.createElement('link');
- link.rel = 'stylesheet';
- link.href = model.css;
- link.media = 'all';
- link.setAttribute("id", css_id);
- head.appendChild(link);
- }
- }
- },
- showMainInternal = function(model) {
- cleanMain();
- main = model;
- loadModelCss(model);
- if(model.uri) {
- mainEle.html(htmlCache[model.uri]);
- }
- mainEle.attr("spa-model-id", model.id);
- if(model.factory && model.factory.main) {
- model.factory.main.call();
- }
- },
- showModalInternal = function(model, data) {
- loadModelCss(model);
- var ly = util.showModal(model.uri ? htmlCache[model.uri] : null);
- ++spa_modal_index;
- ly.ctn.addClass("spa-modal").addClass("spa-modal-index-" + spa_modal_index).attr("spa-model-id", model.id);
- if(model.factory && model.factory.modal) {
- model.factory.modal(data);
- }
- },
- cacheModel = function(model) {
- var m = modelCache[model.id] = {};
- m.uri = model.uri;
- m.factory = model.factory;
- m.css = model.css;
- m.id = model.id;
- m.data = model.data;
- delete resCache[model.id];
- return m;
- },
- afterLoadByMain = function(model, data) {
- showMainInternal(cacheModel(model));
- },
- afterLoadByModal = function(model, data) {
- showModalInternal(cacheModel(model), data);
- },
- loadModel = function(model, handler, data) {
- if(htmlCache[model.uri || "#"]) {
- model.state = 11;
- if(model.script) {
- loadModelScript(model, handler, data);
- } else {
- handler(model, data);
- }
- } else {
- if(cfg.mask) {
- util.showLoading();
- }
- model.state = 10;
- $.ajax({ url: model.uri, dataType: "html", type: "GET" }).done(function(hc) {
- model.state = 11;
- htmlCache[model.uri] = hc;
- if(cfg.mask) {
- util.hideLoading();
- }
- if(model.script) {
- loadModelScript(model, handler, data);
- } else {
- handler(model, data);
- }
- }).fail(function(jqXHR, textStatus, errorThrown) {
- model.state = 12;
- if(cfg.mask) { util.hideLoading(); }
- util.raise({
- code: "loadModelHtml_" + (textStatus || ""),
- msg: textStatus,
- detailMsg: textStatus,
- xhr: jqXHR,
- eObj: errorThrown,
- url: model.uri
- });
- });
- }
- },
- removeModelCss = function(model) {
- if(model.css) {
- var cm = cssCache[model.css];
- if(cm) {
- cm.ref = cm.ref - 1;
- if(!cm.ref) {
- var link = doc.getElementById(cm.id);
- if(link) link.parentNode.removeChild(link);
- delete cssCache[model.css];
- }
- }
- }
- },
- loadModelScript = function(model, handler, data) {
- model.factory = scriptCache[model.script];
- if(model.factory) {
- model.state = 31;
- handler.call(model, data);
- return;
- }
- var node = doc.createElement("script");
- node.async = true;
- node.src = model.script;
- node.charset = "UTF-8";
- var supportOnload = "onload" in node;
- if(cfg.mask) {
- util.showLoading();
- }
- window.spa_define = function(factoryBuilder) {
- model.state = 30;
- if(cfg.mask) {
- util.showLoading();
- }
- try {
- scriptCache[model.script] = model.factory = factoryBuilder(spa);
- model.state = 31;
- if(cfg.mask) {
- util.hideLoading();
- }
- } catch(err) {
- model.state = 32;
- if(cfg.mask) {
- util.hideLoading();
- }
- util.raise({
- code: "buildModelFactory_" + err.toString(),
- msg: err.toString() || "",
- detailMsg: err.toString() || "",
- url: model.script
- });
- }
- handler(model, data);
- };
- if(supportOnload) {
- node.onload = function() {
- if(model.state < 21) model.state = 21;
- node.onerror = null;
- node.onload = null;
- head.removeChild(node);
- if(cfg.mask) {
- util.hideLoading();
- }
- };
- node.onerror = function() {
- node.onload = null;
- node.onerror = null;
- head.removeChild(node);
- if(cfg.mask) {
- util.hideLoading();
- }
- if(model.state < 22) {
- model.state = 22;
- util.raise({
- code: "loadModelScript_",
- msg:"",
- detailMsg: "",
- url: model.script
- });
- }
- };
- } else {
- node.onreadystatechange = function() {
- if(/loaded|complete/.test(node.readyState)) {
- node.onreadystatechange = null;
- if(model.state < 21) {
- model.state = 21;
- var to = model.timeout || 1000;
- setTimeout(function() {
- if(model.state == 21) {
- model.state = 22;
- head.removeChild(node);
- if(cfg.mask) {
- util.hideLoading();
- }
- util.raise({
- code: "loadModelScript_timeout",
- msg: "",
- detailMsg: "",
- url: model.script
- });
- }
- }, model.timeout || 1000);
- } else {
- head.removeChild(node);
- if(cfg.mask) {
- util.hideLoading();
- }
- }
- }
- };
- }
- model.state = 20;
- baseElement ?
- head.insertBefore(node, baseElement) :
- head.appendChild(node);
- },
- cleanMain = function() {
- if(main) {
- removeModelCss(main);
- if(main.factory && main.factory.mainDestory) { main.factory.mainDestory() };
- mainEle.empty();
- main = null;
- }
- },
- getModel = function(id) {
- return modelCache[id];
- },
- showModal = function(id, data) {
- var model = modelCache[id];
- if(model) {
- showModalInternal(model, data);
- } else {
- model = resCache[id];
- if(model) {
- loadModel(model, afterLoadByModal, data);
- } else {
- util.raise({ code: "invalid_model", msg: "不正确的模块[" + id + "]", detailMsg: "不正确的模块[" + id + "]" });
- }
- }
- },
- showMain = function() {
- var id = win.location.hash;
- if(id && id.length > 1) {
- id = id.substring(1);
- } else return;
- if(main && id == main.id) return;
- var model = modelCache[id];
- if(model) {
- showMainInternal(model);
- } else {
- var model = resCache[id];
- if(model) {
- loadModel(model, afterLoadByMain);
- } else {
- util.raise({ code: "invalid_model", msg: "不正确的模块[" + id + "]", detailMsg: "不正确的模块[" + id + "]" });
- }
- }
- },
- getLastModalIndex = function() {
- return spa_modal_index;
- },
- getLastModalCtn = function() {
- return $(".spa-modal-index-" + spa_modal_index);
- },
- getLastModalModel = function() {
- var ctn = $(".spa-modal-index-" + spa_modal_index);
- var id = modalCtn.attr("spa-model-id");
- return getModel(id);
- },
- closeModal = function() {
- var ctn = $(".spa-modal-index-" + spa_modal_index);
- var id = ctn.attr("spa-model-id");
- var inx = util.listModalIndex();
- if(ctn.hasClass("layer-" + inx)) {
- var model = modelCache[id];
- if(model) {
- if(model.factory.modalDestory) {
- model.factory.modalDestory.call(this);
- }
- if(model.css) {
- removeModelCss(model);
- }
- --spa_modal_index;
- util.closeModal();
- }
- } else {
- util.raise({ code: "invalid_dir", msg: "can't close modal:has top layer", detailMsg: "can't close modal:has top layer" });
- }
- },
- build = function(config) {
- $.extend(cfg, config);
- resUri = cfg.resUri || body.attr("resource");
- menuUri = cfg.menuUri || body.attr("menu");
- mainEle = cfg.mainEle || $(".spa-main");
- menuEle = cfg.menuEle || $(".spa-menu");
- resCache = cfg.resCache || resCache;
- htmlCache = cfg.htmlCache || htmlCache;
- htmlCache["#"] = "#";
- if(cfg.loadEnabled) load_res();
- },
- spa = {
- build: build,
- closeModal: closeModal,
- getLastModalModel: getLastModalModel,
- getLastModalCtn: getLastModalCtn,
- getLastModalIndex: getLastModalIndex,
- showMain: showMain,
- showModal: showModal,
- mainChildren:function(selector){
- return mainEle.children(selector);
- },
- modalChildren:function(selector){
- return getLastModalCtn.children(selector);
- },
- findInMain:function(selector){
- return mainEle.find(selector);
- },
- findInModal:function(selector){
- return getLastModalCtn().find(selector);
- }
- };
- $.spa=spa;
- return spa;
- });
|