Skip to content

Commit

Permalink
Updates viewer to allow better Prism highlighting
Browse files Browse the repository at this point in the history
Updates the `panels-viewer.js`, and thus `patternlab-viewer.js`, to improve the way code snippets are highlighted by Prism. This is part of the fix I alluded to for pattern-lab/plugin-node-tab#5.
  • Loading branch information
laurenhamel committed Jan 27, 2019
1 parent 8f631ad commit 736a8c9
Show file tree
Hide file tree
Showing 3 changed files with 255 additions and 109 deletions.
181 changes: 127 additions & 54 deletions dist/styleguide/js/patternlab-viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -875,17 +875,17 @@ Dispatcher.trigger('setupPanels');
var panelsViewer = {

// set up some defaults
targetOrigin: (window.location.protocol === 'file:') ? '*' : window.location.protocol+'//'+window.location.host,
initCopy: false,
initMoveTo: 0,
targetOrigin: (window.location.protocol === 'file:') ? '*' : window.location.protocol + '//' + window.location.host,
initCopy: false,
initMoveTo: 0,

/**
* Check to see if all of the panels have been collected before rendering
* @param {String} the collected panels
* @param {String} the data from the pattern
* @param {Boolean} if this is going to be passed back to the styleguide
*/
checkPanels: function(panels, patternData, iframePassback, switchText) {
* Check to see if all of the panels have been collected before rendering
* @param {String} the collected panels
* @param {String} the data from the pattern
* @param {Boolean} if this is going to be passed back to the styleguide
*/
checkPanels: function (panels, patternData, iframePassback, switchText) {

// count how many panels have rendered content
var panelContentCount = 0;
Expand All @@ -903,11 +903,11 @@ var panelsViewer = {
},

/**
* Gather the panels related to the modal
* @param {String} the data from the pattern
* @param {Boolean} if this is going to be passed back to the styleguide
*/
gatherPanels: function(patternData, iframePassback, switchText) {
* Gather the panels related to the modal
* @param {String} the data from the pattern
* @param {Boolean} if this is going to be passed back to the styleguide
*/
gatherPanels: function (patternData, iframePassback, switchText) {

Dispatcher.addListener('checkPanels', panelsViewer.checkPanels);

Expand All @@ -921,11 +921,13 @@ var panelsViewer = {
for (var i = 0; i < panels.length; ++i) {

panel = panels[i];


panel.index = i;

// catch pattern panel since it doesn't have a name defined by default
if (panel.name === undefined) {
panel.name = patternData.patternEngineName || patternData.patternExtension;
panel.httpRequestReplace = panel.httpRequestReplace+'.'+patternData.patternExtension;
panel.httpRequestReplace = panel.httpRequestReplace + '.' + patternData.patternExtension;
panel.language = patternData.patternExtension;
}

Expand All @@ -935,27 +937,35 @@ var panelsViewer = {

// need a file and then render
var fileBase = urlHandler.getFileName(patternData.patternPartial, false);
var e = new XMLHttpRequest();
e.onload = (function(i, panels, patternData, iframeRequest) {
return function() {
prismedContent = Prism.highlight(this.responseText, Prism.languages['html']);
template = document.getElementById(panels[i].templateID);
templateCompiled = Hogan.compile(template.innerHTML);
templateRendered = templateCompiled.render({ 'language': 'html', 'code': prismedContent });
panels[i].content = templateRendered;

panelsViewer.requestPanel(panel, 'GET', fileBase + panel.httpRequestReplace + '?' + (new Date()).getTime(), true)

.then(function (response) {

prismedContent = Prism.highlight(response.content, Prism.languages[response.panel.language] || Prism.languages.html);
template = document.getElementById(response.panel.templateID);
templateCompiled = Hogan.compile(template.innerHTML);
templateRendered = templateCompiled.render({
'language': 'html',
'code': prismedContent
});
panels[response.panel.index].content = templateRendered;
Dispatcher.trigger('checkPanels', [panels, patternData, iframePassback, switchText]);
};
})(i, panels, patternData, iframePassback);

e.open('GET', fileBase+panel.httpRequestReplace+'?'+(new Date()).getTime(), true);
e.send();

})

.catch(function (error) {

console.log('An error occurred while trying to load panel' + error.panel.name + '.');

});

} else {

// vanilla render of pattern data
template = document.getElementById(panel.templateID);
templateCompiled = Hogan.compile(template.innerHTML);
templateRendered = templateCompiled.render(patternData);
template = document.getElementById(panel.templateID);
templateCompiled = Hogan.compile(template.innerHTML);
templateRendered = templateCompiled.render(patternData);
panels[i].content = templateRendered;
Dispatcher.trigger('checkPanels', [panels, patternData, iframePassback, switchText]);

Expand All @@ -968,19 +978,71 @@ var panelsViewer = {
},

/**
* Render the panels that have been collected
* @param {String} the collected panels
* @param {String} the data from the pattern
* @param {Boolean} if this is going to be passed back to the styleguide
*/
renderPanels: function(panels, patternData, iframePassback, switchText) {
* Request a panel's content via an httpRequest
* @param {Object} the target panel
* @param {String} the request method
* @param {String} the request address
* @param {Boolean} if the request should be async (default) or sync
*/
requestPanel: function (panel, method, url, async) {

async = async ||true;

return new Promise(function (resolve, reject) {

var xhr = new XMLHttpRequest();

xhr.onload = function () {

if (this.status >= 200 && this.status < 300) resolve({
content: xhr.response,
panel: panel
});

else {

reject({
status: xhr.status,
statusText: xhr.statusText,
panel: panel
});
}

};

xhr.onerror = function () {

reject({
status: this.status,
statusText: xhr.statusText,
panel: panel
});

};

xhr.open(method, url, async);

xhr.send();

});

},


/**
* Render the panels that have been collected
* @param {String} the collected panels
* @param {String} the data from the pattern
* @param {Boolean} if this is going to be passed back to the styleguide
*/
renderPanels: function (panels, patternData, iframePassback, switchText) {

// set-up defaults
var template, templateCompiled, templateRendered;
var annotation, comment, count, div, els, item, markup, i;
var patternPartial = patternData.patternPartial;
patternData.panels = panels;

// set a default pattern description for modal pop-up
if (!iframePassback && (patternData.patternDesc.length === 0)) {
patternData.patternDesc = "This pattern doesn't have a description.";
Expand All @@ -990,7 +1052,7 @@ var panelsViewer = {
patternData.patternNameCaps = patternData.patternName.toUpperCase();

// check for annotations in the given mark-up
markup = document.createElement('div');
markup = document.createElement('div');
markup.innerHTML = patternData.patternMarkup;

count = 1;
Expand All @@ -1000,10 +1062,15 @@ var panelsViewer = {
for (i = 0; i < comments.comments.length; ++i) {

item = comments.comments[i];
els = markup.querySelectorAll(item.el);
els = markup.querySelectorAll(item.el);

if (els.length > 0) {
annotation = { 'displayNumber': count, 'el': item.el, 'title': item.title, 'comment': item.comment };
annotation = {
'displayNumber': count,
'el': item.el,
'title': item.title,
'comment': item.comment
};
patternData.annotations.push(annotation);
count++;
}
Expand All @@ -1012,7 +1079,10 @@ var panelsViewer = {

// alert the pattern that annotations should be highlighted
if (patternData.annotations.length > 0) {
var obj = JSON.stringify({ 'event': 'patternLab.annotationsHighlightShow', 'annotations': patternData.annotations });
var obj = JSON.stringify({
'event': 'patternLab.annotationsHighlightShow',
'annotations': patternData.annotations
});
document.getElementById('sg-viewport').contentWindow.postMessage(obj, panelsViewer.targetOrigin);
}

Expand Down Expand Up @@ -1046,25 +1116,25 @@ var panelsViewer = {

// figure out if pattern state should be drawn
patternData.patternStateExists = (patternData.patternState.length > 0);

// figure if annotations should be drawn
patternData.annotationExists = (patternData.annotations.length > 0);

// figure if the entire desc block should be drawn
patternData.descBlockExists = (patternData.patternDescExists || patternData.lineageExists || patternData.lineageRExists || patternData.patternStateExists || patternData.annotationExists);

// set isPatternView based on if we have to pass it back to the styleguide level
patternData.isPatternView = (iframePassback === false);

// render all of the panels in the base panel template
template = document.getElementById('pl-panel-template-base');
template = document.getElementById('pl-panel-template-base');
templateCompiled = Hogan.compile(template.innerHTML);
templateRendered = templateCompiled.render(patternData);

// make sure templateRendered is modified to be an HTML element
div = document.createElement('div');
div.className = 'sg-modal-content-inner';
div.innerHTML = templateRendered;
div = document.createElement('div');
div.className = 'sg-modal-content-inner';
div.innerHTML = templateRendered;
templateRendered = div;

// add click events
Expand All @@ -1076,8 +1146,8 @@ var panelsViewer = {
panel = panels[i];

// default IDs
panelTab = '#sg-'+patternPartial+'-'+panel.id+'-tab';
panelBlock = '#sg-'+patternPartial+'-'+panel.id+'-panel';
panelTab = '#sg-' + patternPartial + '-' + panel.id + '-tab';
panelBlock = '#sg-' + patternPartial + '-' + panel.id + '-panel';

// show default options
if ((templateRendered.querySelector(panelTab) !== null) && (panel.default)) {
Expand All @@ -1088,9 +1158,12 @@ var panelsViewer = {
}

// find lineage links in the rendered content and add postmessage handlers in case it's in the modal
$('#sg-code-lineage-fill a, #sg-code-lineager-fill a', templateRendered).on('click', function(e){
$('#sg-code-lineage-fill a, #sg-code-lineager-fill a', templateRendered).on('click', function (e) {
e.preventDefault();
var obj = JSON.stringify({ 'event': 'patternLab.updatePath', 'path': urlHandler.getFileName($(this).attr('data-patternpartial')) });
var obj = JSON.stringify({
'event': 'patternLab.updatePath',
'path': urlHandler.getFileName($(this).attr('data-patternpartial'))
});
document.getElementById('sg-viewport').contentWindow.postMessage(obj, panelsViewer.targetOrigin);
});

Expand Down
Loading

0 comments on commit 736a8c9

Please sign in to comment.