Skip to content

Instantly share code, notes, and snippets.

@mrsweaters
Created June 19, 2019 16:25
Show Gist options
  • Save mrsweaters/06c7632aecb02752b44bcdbced777271 to your computer and use it in GitHub Desktop.
Save mrsweaters/06c7632aecb02752b44bcdbced777271 to your computer and use it in GitHub Desktop.
SVG INJECT DIRECTIVES
const SvgInjectFillContentDirective = $compile => ({
restrict: "ECA",
priority: -400,
require: "svgInject",
link(scope, $element, $attr, ctrl) {
if (toString.call($element[0]).match(/SVG/)) {
// WebKit: https://bugs.webkit.org/show_bug.cgi?id=135698 --- SVG elements do not
// support innerHTML, so detect this here and try to generate the contents
// specially.
$element.empty();
$compile(jqLiteBuildFragment(ctrl.template, window.document).childNodes)(
scope,
function namespaceAdaptedClone(clone) {
$element.append(clone);
},
{ futureParentElement: $element }
);
return;
}
$element.html(ctrl.template);
$compile($element.contents())(scope);
}
});
SvgInjectFillContentDirective.$inject = ["$compile"];
export default SvgInjectFillContentDirective;
const SvgInjectDirective = ($templateRequest, $anchorScroll, $animate) => ({
restrict: "ECA",
priority: 400,
terminal: true,
transclude: "element",
controller: angular.noop,
compile(element, attr) {
var srcExp = require(attr.ngInclude || attr.src),
onloadExp = attr.onload || "",
autoScrollExp = attr.autoscroll;
return function(scope, $element, $attr, ctrl, $transclude) {
var changeCounter = 0,
currentScope,
previousElement,
currentElement;
var cleanupLastIncludeContent = function() {
if (previousElement) {
previousElement.remove();
previousElement = null;
}
if (currentScope) {
currentScope.$destroy();
currentScope = null;
}
if (currentElement) {
$animate.leave(currentElement).done(function(response) {
if (response !== false) previousElement = null;
});
previousElement = currentElement;
currentElement = null;
}
};
scope.$watch(srcExp, function ngIncludeWatchAction(src) {
var afterAnimation = function(response) {
if (
response !== false &&
isDefined(autoScrollExp) &&
(!autoScrollExp || scope.$eval(autoScrollExp))
) {
$anchorScroll();
}
};
var thisChangeId = ++changeCounter;
if (src) {
//set the 2nd param to true to ignore the template request error so that the inner
//contents and scope can be cleaned up.
$templateRequest(src, true).then(
function(response) {
if (scope.$$destroyed) return;
if (thisChangeId !== changeCounter) return;
var newScope = scope.$new();
ctrl.template = response;
// Note: This will also link all children of ng-include that were contained in the original
// html. If that content contains controllers, ... they could pollute/change the scope.
// However, using ng-include on an element with additional content does not make sense...
// Note: We can't remove them in the cloneAttchFn of $transclude as that
// function is called before linking the content, which would apply child
// directives to non existing elements.
var clone = $transclude(newScope, function(clone) {
cleanupLastIncludeContent();
$animate.enter(clone, null, $element).done(afterAnimation);
});
currentScope = newScope;
currentElement = clone;
currentScope.$emit("$includeContentLoaded", src);
scope.$eval(onloadExp);
},
function() {
if (scope.$$destroyed) return;
if (thisChangeId === changeCounter) {
cleanupLastIncludeContent();
scope.$emit("$includeContentError", src);
}
}
);
scope.$emit("$includeContentRequested", src);
} else {
cleanupLastIncludeContent();
ctrl.template = null;
}
});
};
}
});
SvgInjectDirective.$inject = ["$templateRequest", "$anchorScroll", "$animate"];
export default SvgInjectDirective;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment