Skip to content

Commit

Permalink
Add possibility to disable shadow DOM encapsulation
Browse files Browse the repository at this point in the history
  • Loading branch information
Hannu Pelkonen committed Mar 27, 2015
1 parent 33c60ef commit 472730b
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 8 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@ This allows Angular to deal with the routing. However, the static files should b

By default variable definitions are searched from every file passed in gulp.src. styleVariables parameter could be used to filter from which files variables are loaded.

<a name="option-disableEncapsulation"></a>
**disableEncapsulation** (boolean, optional, default: false)

Disable Shadow DOM encapsulation. When this option parameter is enabled, all styles are defined in page head and markup examples are not encapsulated using Shadow DOM.

<a name="option-filesConfig"></a>
**filesConfig** (array, optional) **(Experimental feature)**

Expand Down
8 changes: 8 additions & 0 deletions lib/app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,17 @@
head.appendChild(link);
}

{{#disableEncapsulation}}
// Always use "global" styles
userStyleFiles.forEach(addCssLink);
{{/disableEncapsulation}}

{{^disableEncapsulation}}
// Use Shadow DOM but fallback to global styles if shadow DOM is not supported
if (typeof head.createShadowRoot !== 'function') {
userStyleFiles.forEach(addCssLink);
}
{{/disableEncapsulation}}
}());
</script>
<script type="text/ng-template" id="userStyles.html">
Expand Down
4 changes: 2 additions & 2 deletions lib/app/js/directives/shadowDom.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
'use strict';

angular.module('sgApp')
.directive('shadowDom', function($templateCache) {
.directive('shadowDom', function(Styleguide, $templateCache) {

var USER_STYLES_TEMPLATE = 'userStyles.html';

return {
restrict: 'E',
transclude: true,
link: function(scope, element, attrs, controller, transclude) {
if (typeof element[0].createShadowRoot === 'function') {
if (typeof element[0].createShadowRoot === 'function' && !Styleguide.config.data.disableEncapsulation) {
var root = angular.element(element[0].createShadowRoot());
root.append($templateCache.get(USER_STYLES_TEMPLATE));
transclude(function(clone) {
Expand Down
4 changes: 3 additions & 1 deletion lib/styleguide.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ function sanitizeOptions(opt) {
kssOpt: opt.kssOpt || {},
overviewPath: opt.overviewPath || path.join(__dirname, '/overview.md'),
extraHead: (typeof opt.extraHead === 'object') ? opt.extraHead.join('\n') : opt.extraHead,
disableEncapsulation: opt.disableEncapsulation || false,
appRoot: opt.appRoot || '',
commonClass: opt.commonClass || '',
styleVariables: opt.styleVariables || false,
Expand Down Expand Up @@ -84,7 +85,7 @@ function generateInheritedWrappers(json) {
}

function copyUsedOptionsToJsonConfig(opt, json) {
var used = ['appRoot', 'extraHead', 'commonClass', 'title'];
var used = ['appRoot', 'extraHead', 'commonClass', 'title', 'disableEncapsulation'];
json.config = {};
used.forEach(function(prop) {
json.config[prop] = _.cloneDeep(opt[prop]);
Expand Down Expand Up @@ -248,6 +249,7 @@ module.exports.generate = function(options) {
.pipe(mustache({
title: opt.title,
extraHead: opt.extraHead,
disableEncapsulation: opt.disableEncapsulation,
appRoot: opt.appRoot,
socketIo: opt.server,
filesConfig: JSON.stringify(opt.filesConfig)
Expand Down
39 changes: 34 additions & 5 deletions test/angular/unit/directives/shadowDom.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
describe('shadowDom directive', function() {

var $scope, elem, shadowRoot, originalCreateShadowRoot, result,
userStyleTemplate = '<style>@import(\'style.css\');</style>',
html = '<shadow-dom><p>hi!</p></shadow-dom>';
styleguideMock,
userStyleTemplate = '<style>@import(\'style.css\');</style>',
html = '<shadow-dom><p>hi!</p></shadow-dom>';

beforeEach(module('sgApp'));

describe('when Element.createShadowRoot is a function', function() {
beforeEach(module(function($provide) {
styleguideMock = {
config: {
data: {}
}
};
$provide.value('Styleguide', styleguideMock);
}));

describe('when Element.createShadowRoot is a function', function() {
before(mockCreateShadowRoot);
after(restoreCreateShadowRoot);
beforeEach(create);
Expand All @@ -23,11 +32,9 @@ describe('shadowDom directive', function() {
it('appends tag contents into shadowRoot after styles', function() {
expect(shadowRoot.childNodes[1].outerHTML).to.eql('<p class="ng-scope">hi!</p>');
});

});

describe('when Element.createShadowRoot is a not a function', function() {

before(disableCreateShadowRoot);
after(restoreCreateShadowRoot);
beforeEach(create);
Expand All @@ -39,7 +46,29 @@ describe('shadowDom directive', function() {
it('appends shadow-dom tag contents as is', function() {
expect(elem.html()).to.eql('<p class="ng-scope">hi!</p>');
});
});

describe('when disableEncapsulation config parameter is enabled', function() {
beforeEach(module(function($provide) {
styleguideMock = {
config: {
data: {
disableEncapsulation: true
}
}
};
$provide.value('Styleguide', styleguideMock);
}));

beforeEach(create);

it('does not create a shadow root', function() {
expect(shadowRoot).to.eql(undefined);
});

it('appends shadow-dom tag contents as is', function() {
expect(elem.html()).to.eql('<p class="ng-scope">hi!</p>');
});
});

function mockCreateShadowRoot() {
Expand Down

0 comments on commit 472730b

Please sign in to comment.