Skip to content

Instantly share code, notes, and snippets.

@rjgotten
Last active May 23, 2019 13:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rjgotten/1bdc23e0f04a1c46af44eeb5fd08a063 to your computer and use it in GitHub Desktop.
Save rjgotten/1bdc23e0f04a1c46af44eeb5fd08a063 to your computer and use it in GitHub Desktop.
var loaderUtils = require("loader-utils");
var parse = require("can-stache-ast").parse;
function makeRenderer(imports, intermediate, filename) {
intermediate = JSON.stringify(intermediate);
filename = JSON.stringify(filename);
imports = imports.map(function(imported) {
imported = JSON.stringify(imported);
return `${imported} : Promise.resolve(require(${imported}))`
}).join(',\n');
return `
var stache = require('can-stache');
var mustacheCore = require( "can-stache/src/mustache_core" );
var parse = require("can-stache-ast").parse;
//common deps
require('can-view-import');
require('can-stache-bindings');
//view-specific import deps
var imports = { ${imports} };
${
filename ?
`var renderer = stache(${filename}, ${intermediate})` :
`var renderer = stache(${intermediate}) ;`
}
module.exports = function(scope, options, nodeList) {
var moduleOptions = Object.assign({}, options);
let _module = {
id: module.id,
importer: function(moduleName) { return imports[moduleName] }
};
if (moduleOptions.helpers) {
moduleOptions.helpers = Object.assign({ module: _module }, moduleOptions.helpers);
} else {
moduleOptions.module = _module;
}
return renderer( scope, moduleOptions, nodeList );
};
`;
}
module.exports = function(source, map) {
var filename = loaderUtils.getRemainingRequest(this);
var ast = parse(filename, source);
var callback = this.async();
Promise.all([
ast.dynamicImports
]).then(function(results) {
var imports = results[0];
ast.imports.unshift.apply(ast.imports, imports);
var renderer = makeRenderer(
ast.imports,
ast.intermediate,
filename
);
callback(null, renderer, map);
});
};
"use strict";
var assign = require('can-assign');
var canData = require('can-dom-data');
var canSymbol = require('can-symbol');
var DOCUMENT = require("can-globals/document/document");
var getChildNodes = require('can-child-nodes');
var importer = require('can-import-module');
var domMutate = require('can-dom-mutate');
var domMutateNode = require("can-dom-mutate/node");
var nodeLists = require('can-view-nodelist');
var viewCallbacks = require('can-view-callbacks');
var tag = viewCallbacks.tag;
var canLog = require("can-log/");
var dev = require("can-log/dev/dev");
function setViewModel (element, viewModel) {
element[canSymbol.for('can.viewModel')] = viewModel;
}
function processImport(el, tagData) {
var moduleName = el.getAttribute("from");
// If the module is part of the helpers pass that into can.import
// as the parentName
var templateModule = tagData.scope.get("scope.helpers.module");
var parentName = templateModule ? templateModule.id : undefined;
if(!moduleName) {
return Promise.reject("No module name provided");
}
var importPromise = templateModule && typeof templateModule.importer === "function"
? templateModule.importer(moduleName, parentName)
: importer(moduleName, parentName);
importPromise.catch(function(err) {
canLog.error(err);
});
// Set the viewModel to the promise
setViewModel(el, importPromise);
canData.set(el, "scope", importPromise);
// Set the scope
var scope = tagData.scope.add(importPromise, { notContext: true });
// If there is a can-tag present we will hand-off rendering to that tag.
var handOffTag = el.getAttribute("can-tag");
if(handOffTag) {
var callback = tag(handOffTag);
// Verify hand off tag has been registered. Callback can be undefined or noop.
if (!callback || callback === viewCallbacks.defaultCallback) {
//!steal-remove-start
dev.error(new Error("The tag '" + handOffTag + "' has not been properly registered."));
//!steal-remove-end
} else {
canData.set(el, "preventDataBindings", true);
callback(el, assign(tagData, {
scope: scope
}));
canData.set(el, "preventDataBindings", false);
setViewModel(el, importPromise);
canData.set(el, "scope", importPromise);
}
}
// Render the subtemplate and register nodeLists
else {
var nodeList = nodeLists.register([], undefined, tagData.parentNodeList || true, false);
nodeList.expression = "<" + this.tagName + ">";
var frag = tagData.subtemplate ?
tagData.subtemplate(scope, tagData.options, nodeList) :
DOCUMENT().createDocumentFragment();
var removalDisposal = domMutate.onNodeRemoval(el, function () {
var doc = el.ownerDocument;
var ownerNode = doc.contains ? doc : doc.documentElement;
if (!ownerNode || ownerNode.contains(el) === false) {
removalDisposal();
nodeLists.unregister(nodeList);
}
});
domMutateNode.appendChild.call(el, frag);
nodeLists.update(nodeList, getChildNodes(el));
}
}
["can-import", "can-dynamic-import"].forEach(function(tagName) {
tag(tagName, processImport.bind({ tagName: tagName }));
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment