UNPKG

fis3-prepackager-imweb-ques

Version:

fis3 prepackager plugin for q components of imweb team

163 lines (142 loc) 4.01 kB
var map = require('map-stream') , path = require('path') , fs = require('fs') , cheerio = require('cheerio') , _ = require('lodash') , walker = require('../utils/walker') , TagSet = require('../utils/tagSet') , Tag = require('./tag') , utils = require('../utils/components'); /** * Page * @class * @param {String} str */ function Page(str, options) { str = (str || '').trim() || '<div></div>'; this._init(str, options); } var p = Page.prototype; p._init = function (str, options) { options = options || {}; this.getComp = options.getComp; this.options = options; this.$ = cheerio.load(str, { decodeEntities: false }); // this page's custom targets this.customTags = new TagSet(); // this page's ui targets this.uiTags = new TagSet(); // uid for component this.uid = 0; // TODO this.param = { disabled: {} }; // build all custom elements this.buildTag(); }; p.appendCss = function(path) { this.$('head').append('<link rel="stylesheet" href="' + path + '"/>'); }; p.appendJs = function(path) { this.insertJs('<script src="' + path + '"></script>'); }; p.appendJsCode = function(code) { this.insertJs('<script>' + code + '</script>'); }; p.insertJs = function(node) { var self = this; if (self._$jsbefore) { self._$jsbefore.before(node); } else if (self._$jsbefore === null) { self.$('body').before(node); } else { self.$('body script').each(function(i, item) { if (!item.attribs.src) { self._$jsbefore = cheerio(item); return false; } }); self._$jsbefore = self._$jsbefore || null; self.insertJs(node); } }; p.buildTag = function () { var self = this , $ = this.$ , tags = new TagSet() , param = this.param , customTags = this.customTags , uiTags = this.uiTags , deps = {}; // find all targets in body walker.tags($('body'), function (node) { tags.add(node.name); }); // find all custom targets tags.custom().forEach(function (customTag) { // feature flag // remove all disabled custom element if (param.disabled[customTag]) return $(customTag).remove(); var comp = self.getComp(customTag); // if the component exist if (comp) { // diy target if (/^diy-/.test(customTag)) { // clear module cache delete require.cache[comp.jsPath]; // just do it yourself try { require(comp.jsPath).call(self, { tagName: customTag, $: $, container: $(customTag) }); } catch(e) { self.logError(e.message + ' in ' + comp.jsPath); } // ui target } else if (/^ui-/.test(customTag)) { uiTags.add(customTag); var fragmentTpl = new Tag(comp, _.extend({}, self.options, { ret: 'function' })).tpl , $customTag = $(customTag); $customTag.each(function (i, ele) { ele = $(ele); ele.replaceWith(utils.makeFragment($, ele, fragmentTpl)) }); } else { customTags.add(customTag); // build fragment template var tag = new Tag(comp, _.extend({}, self.options, { ret: 'function' })) , fragmentTpl = tag.tpl , $customTag = $(customTag); tag.dependences.values() .forEach(function (dep) { deps[dep] = deps[dep] || self.getComp(dep); }); // destroy tag tag.destroy(); tag = null; // set dep uid comp.uid = ++self.uid; comp.child = 1; // set dep deps[comp.name] = comp; // replace all custom targets $customTag.each(function (i, ele) { ele = $(ele); ele.replaceWith(utils.makeFragment($, ele, fragmentTpl, comp.uid)); }); } } }); this.deps = deps; }; p.destroy = function () { // TODO }; module.exports = Page;