Skip to content

Commit 2a7f294

Browse files
committed
Added a method to sandbox project styles to avoid style collisions.
1 parent de3fb4a commit 2a7f294

3 files changed

Lines changed: 142 additions & 26 deletions

File tree

_template/app/js/main.js

Lines changed: 110 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
const Vue = require('vue/dist/vue');
2+
const hljs = require('highlightjs');
3+
const marked = require('marked');
4+
const smoothScroll = require('smooth-scroll');
5+
const postcss = require('postcss');
6+
const prefixer = require('postcss-prefix-selector');
7+
8+
Vue.use(require('vue-resource'));
9+
10+
111
/**
212
* Component component
313
*/
@@ -22,7 +32,7 @@ var ndplComponent = Vue.extend({
2232
styles = '';
2333

2434
// These inline style are only applied after the component has fully loaded
25-
if(_this.loaded) {
35+
if(_this.components_loaded) {
2636
if(_this.component.options.sample_min_height) {
2737
styles += 'min-height:' + _this.component.options.sample_min_height + 'px;';
2838
}
@@ -54,24 +64,24 @@ var ndplComponent = Vue.extend({
5464
var _this = this;
5565

5666
// Listen for loaded event
57-
Astrum.$on('loaded', function() {
67+
Astrum.$on('components_loaded', function() {
5868

5969
// Monitor scroll and resize events and update navigation active state appropirately
6070
window.addEventListener('scroll', _this.updateActive);
6171
window.addEventListener('resize', _this.updateActive);
6272

6373
_this.setHideSample(function() {
64-
_this.loaded = true;
74+
_this.components_loaded = true;
6575
});
6676
});
6777

6878
// Listen for resizing event
6979
Astrum.$on('resizing', function(is_resizing) {
70-
_this.loaded = false;
80+
_this.components_loaded = false;
7181

7282
if(! is_resizing) {
7383
_this.setHideSample(function() {
74-
_this.loaded = true;
84+
_this.components_loaded = true;
7585
});
7686
}
7787
});
@@ -88,13 +98,13 @@ var ndplComponent = Vue.extend({
8898
*/
8999
updateActive: function() {
90100
var _this = this;
91-
101+
92102
// If scroll position is great than or equal to component offset top - 60 pixels
93103
// and scroll position is less than component offset top plus component height plus 60 pixels
94104
// and active component is not this component
95105
if(_this.$root && _this.$root.scroll_position >= _this.$el.offsetTop - 60 &&
96106
_this.$root.scroll_position < _this.$el.offsetTop + _this.$el.offsetHeight) {
97-
107+
98108
// If not currently auto scrolling to component
99109
// and component is not active
100110
if(!_this.$root.scrolling_to &&
@@ -291,10 +301,14 @@ var Astrum = new Vue({
291301
},
292302
components_count: 0,
293303
groups_count: 0,
304+
stylesheets_count: 0,
294305
components_loaded_count: 0,
295306
groups_loaded_count: 0,
307+
stylesheets_loaded_count: 0,
296308
groups_loaded: false,
297-
loaded: false,
309+
components_loaded: false,
310+
stylesheets_loaded: false,
311+
styles: null,
298312
resizing: false,
299313
typekit_loaded: false,
300314
scroll_position: 0,
@@ -313,7 +327,7 @@ var Astrum = new Vue({
313327
rtime: new Date(1, 1, 2000, 12,00,00),
314328
timeout: false,
315329
delta: 200,
316-
return_load_time: true,
330+
return_load_time: false,
317331
version: null
318332
},
319333

@@ -376,6 +390,12 @@ var Astrum = new Vue({
376390
}
377391

378392
return styles;
393+
},
394+
395+
loaded: function() {
396+
var _this = this;
397+
398+
return _this.components_loaded && _this.stylesheets_loaded;
379399
}
380400
},
381401

@@ -385,15 +405,38 @@ var Astrum = new Vue({
385405

386406
_this.setupComponents();
387407
},
388-
loaded: function() {
408+
409+
components_loaded: function() {
389410
var _this = this;
390411

391-
if (_this.loaded === true) {
412+
if (_this.components_loaded === true) {
392413
_this.scrollTo(window.location.hash);
393414

394415
_this.injectProjectScripts();
395416

396-
Astrum.$emit('loaded');
417+
Astrum.$emit('components_loaded');
418+
}
419+
},
420+
421+
stylesheets_loaded: function() {
422+
var _this = this;
423+
424+
if (_this.stylesheets_loaded === true) {
425+
var head = document.getElementsByTagName('head').item(0),
426+
style,
427+
output;
428+
429+
output = postcss().use(prefixer({
430+
prefix: '.ndpl-component__sample'
431+
})).process(_this.styles).css;
432+
433+
// Inject inline styles for Astrum theme override.
434+
style = document.createElement('style');
435+
436+
style.type = 'text/css';
437+
style.appendChild(document.createTextNode(output));
438+
439+
head.appendChild(style);
397440
}
398441
}
399442
},
@@ -451,20 +494,37 @@ var Astrum = new Vue({
451494

452495
methods: {
453496

497+
/**
498+
* Inject project styles into head.
499+
*/
454500
injectProjectStyles: function() {
455-
var _this = this,
456-
head = document.getElementsByTagName('head').item(0);
501+
var _this = this;
457502

458-
for (var i = 0; i < _this.assets.css.length; i++) {
459-
var link = document.createElement('link');
503+
// If there are no stylesheets we mark them as loaded.
504+
if (! _this.assets.css.length) {
505+
_this.stylesheets_loaded = true;
506+
return;
507+
}
460508

461-
link.rel = 'stylesheet';
462-
link.href = _this.assets.css[i];
509+
_this.styles = '';
510+
_this.stylesheets_count = _this.assets.css.length;
463511

464-
head.appendChild(link);
512+
for (var i = 0; i < _this.assets.css.length; i++) {
513+
var stylesheet = _this.assets.css[i];
514+
515+
// Get and set concatenate css.
516+
_this.$http.get(stylesheet + '?cb=' + new Date()).then(function (response) {
517+
_this.styles += response.data;
518+
_this.areStylesheetsLoaded();
519+
}, function (response) {
520+
_this.logError('Stylesheet failed to load from <code>' + response.url.split('?')[0] + '</code>');
521+
});
465522
}
466523
},
467524

525+
/**
526+
* Inject theme styles into head.
527+
*/
468528
injectThemeStyles: function() {
469529
var _this = this,
470530
head = document.getElementsByTagName('head').item(0),
@@ -515,6 +575,9 @@ var Astrum = new Vue({
515575
}
516576
},
517577

578+
/**
579+
* Inject font libraries into head.
580+
*/
518581
injectFontLibraries: function() {
519582
var _this = this,
520583
head = document.getElementsByTagName('head').item(0),
@@ -557,6 +620,9 @@ var Astrum = new Vue({
557620
}
558621
},
559622

623+
/**
624+
* Inject project scripts into body.
625+
*/
560626
injectProjectScripts: function() {
561627
var _this = this,
562628
body = document.getElementsByTagName('body')[0];
@@ -570,6 +636,9 @@ var Astrum = new Vue({
570636
}
571637
},
572638

639+
/**
640+
* Inject meta tags into head.
641+
*/
573642
injectMeta: function() {
574643
var _this = this,
575644
head = document.getElementsByTagName('head').item(0);
@@ -710,6 +779,9 @@ var Astrum = new Vue({
710779
}
711780
},
712781

782+
/**
783+
* Setup components.
784+
*/
713785
setupComponents: function() {
714786
var _this = this;
715787

@@ -777,7 +849,7 @@ var Astrum = new Vue({
777849
component.html = response.data;
778850
_this.areComponentsLoaded();
779851
}, function () {
780-
_this.logError('HTML file for <strong>' + component.name + '</strong> component failed to load from <code>' + component_path + '/html.md</code>');
852+
_this.logError('HTML file for <strong>' + component.name + '</strong> component failed to load from <code>' + component_path + '/html.md</code>');
781853
});
782854

783855
// Get and set component description
@@ -816,13 +888,29 @@ var Astrum = new Vue({
816888
if (_this.components_loaded_count === _this.components_count * 2) {
817889

818890
setTimeout(function() {
819-
_this.loaded = true;
891+
_this.components_loaded = true;
820892

821893
if (_this.return_load_time) console.timeEnd('Astrum loaded in');
822894
}, 2000);
823895
}
824896
},
825897

898+
/**
899+
* Increment stylesheets loaded.
900+
*/
901+
areStylesheetsLoaded: function() {
902+
var _this = this;
903+
904+
_this.stylesheets_loaded_count += 1;
905+
906+
if (_this.stylesheets_loaded_count === _this.stylesheets_count) {
907+
908+
setTimeout(function() {
909+
_this.stylesheets_loaded = true;
910+
}, 2000);
911+
}
912+
},
913+
826914
/**
827915
* Add to log.
828916
*
@@ -913,10 +1001,9 @@ var Astrum = new Vue({
9131001
offset = _this.mobile_view ? 79 : 30;
9141002

9151003
if(!hash) return;
916-
9171004
_this.scrolling_to = true;
9181005

919-
smoothScroll.animateScroll(hash, null, {
1006+
smoothScroll.animateScroll(document.querySelector(hash), null, {
9201007
offset: offset,
9211008
callback: function() {
9221009
_this.scrolling_to = false;

0 commit comments

Comments
 (0)