(function ()
{
'use strict';
angular
.module('app.components.material-docs')
.directive('demoInclude', demoInclude)
function demoInclude($q, $http, $compile, $templateCache, $timeout)
{
return {
restrict: 'E',
link : postLink
};
function postLink(scope, element, attr)
{
var demoContainer;
// Interpret the expression given as `demo-include files="something"`
var files = scope.$eval(attr.files) || {};
var ngModule = scope.$eval(attr.module) || '';
$timeout(handleDemoIndexFile);
/**
* Fetch the index file, and if it contains its own ngModule
* then bootstrap a new angular app with that ngModule. Otherwise, compile
* the demo into the current ng-app.
*/
function handleDemoIndexFile()
{
files.index.contentsPromise.then(function (contents)
{
demoContainer = angular.element(
'<div class="demo-content ' + ngModule + '">'
);
var isStandalone = !!ngModule;
var demoScope;
var demoCompileService;
if ( isStandalone )
{
angular.bootstrap(demoContainer[0], [ngModule]);
demoScope = demoContainer.scope();
demoCompileService = demoContainer.injector().get('$compile');
scope.$on('$destroy', function ()
{
demoScope.$destroy();
});
}
else
{
demoScope = scope.$new();
demoCompileService = $compile;
}
// Once everything is loaded, put the demo into the DOM
$q.all([
handleDemoStyles(),
handleDemoTemplates()
]).finally(function ()
{
demoScope.$evalAsync(function ()
{
element.append(demoContainer);
demoContainer.html(contents);
demoCompileService(demoContainer.contents())(demoScope);
});
});
});
}
/**
* Fetch the demo styles, and append them to the DOM.
*/
function handleDemoStyles()
{
return $q.all(files.css.map(function (file)
{
return file.contentsPromise;
}))
.then(function (styles)
{
styles = styles.join('\n'); //join styles as one string
var styleElement = angular.element('<style>' + styles + '</style>');
document.body.appendChild(styleElement[0]);
scope.$on('$destroy', function ()
{
styleElement.remove();
});
});
}
/**
* Fetch the templates for this demo, and put the templates into
* the demo app's templateCache, with a url that allows the demo apps
* to reference their templates local to the demo index file.
*
* For example, make it so the dialog demo can reference templateUrl
* 'my-dialog.tmpl.html' instead of having to reference the url
* 'generated/material.components.dialog/demo/demo1/my-dialog.tmpl.html'.
*/
function handleDemoTemplates()
{
return $q.all(files.html.map(function (file)
{
return file.contentsPromise.then(function (contents)
{
// Get the $templateCache instance that goes with the demo's specific ng-app.
var demoTemplateCache = demoContainer.injector().get('$templateCache');
demoTemplateCache.put(file.name, contents);
scope.$on('$destroy', function ()
{
demoTemplateCache.remove(file.name);
});
});
}));
}
}
}
})(); |