1
0
mirror of https://github.com/pattern-lab/patternlab-php.git synced 2025-03-15 19:39:42 +01:00

smarter handling of pattern annotations

This commit is contained in:
Dave Olsen 2013-10-26 11:43:54 -04:00
parent 6693c9595c
commit 9374d4ae82
2 changed files with 194 additions and 36 deletions

View File

@ -1,5 +1,5 @@
/*!
* Annotations Support for Patterns - v0.2
* Annotations Support for Patterns - v0.3
*
* Copyright (c) 2013 Dave Olsen, http://dmolsen.com
* Licensed under the MIT license
@ -8,35 +8,119 @@
var annotationsPattern = {
commentsActive: false,
commentsOverlayActive: false,
commentsOverlay: false,
commentsOverlayElement: "",
commentsEmbeddedActive: false,
commentsEmbedded: false,
/**
* add an onclick handler to each element in the pattern that has an annotation
*/
showComments: function() {
for (comment in comments.comments) {
var item = comments.comments[comment];
var els = document.querySelectorAll(item.el);
for (var i = 0; i < els.length; ++i) {
els[i].onclick = (function(item) {
return function(e) {
if (annotationsPattern.commentsActive) {
// make sure this only added when we're on a pattern specific view
var body = document.getElementsByTagName("body");
if (!body[0].classList.contains("pattern-list")) {
for (comment in comments.comments) {
var item = comments.comments[comment];
var els = document.querySelectorAll(item.el);
for (var i = 0; i < els.length; ++i) {
els[i].onclick = (function(item) {
return function(e) {
e.preventDefault();
e.stopPropagation();
var obj = { "el": item.el, "title": item.title, "comment": item.comment };
var obj = {};
if (annotationsPattern.commentsOverlayActive && !annotationsPattern.commentsOverlay) {
// if this is for an overlay and comments overlay is false set the payload to turn the overlay on
annotationsPattern.commentsOverlay = true;
obj = { "commentOverlay": "on", "swapOverlay": false, "el": item.el, "title": item.title, "comment": item.comment };
} else if (annotationsPattern.commentsOverlayActive && annotationsPattern.commentsOverlay) {
if (item.el == annotationsPattern.commentsOverlayElement) {
// if the last element was clicked again turn off the overlay
annotationsPattern.commentsOverlay = false;
obj = { "commentOverlay": "off" };
} else {
// if an element was clicked on while the overlay was already on swap it
obj = { "commentOverlay": "on", "swapOverlay": true, "el": item.el, "title": item.title, "comment": item.comment };
}
}
annotationsPattern.commentsOverlayElement = item.el;
var targetOrigin = (window.location.protocol == "file:") ? "*" : window.location.protocol+"//"+window.location.host;
parent.postMessage(obj,targetOrigin);
}
}
})(item);
})(item);
}
}
}
},
},
/**
* toggle the has-comment class on/off based on user clicking in the viewer UI
* embed a comment by building the sg-annotations div (if necessary) and building an sg-annotation div
* @param {Object} element to check the parent node of
* @param {String} the title of the comment
* @param {String} the comment HTML
*/
embedComments: function (el,title,comment) {
// build the annotation div and add the content to it
var annotationDiv = document.createElement("div");
annotationDiv.classList.add("sg-annotation");
var h3 = document.createElement("h3");
var p = document.createElement("p");
h3.innerHTML = title;
p.innerHTML = comment;
annotationDiv.appendChild(h3);
annotationDiv.appendChild(p);
// find the parent element to attach things to
var parentEl = annotationsPattern.findParent(el);
// see if a child with the class annotations exists
var els = parentEl.getElementsByClassName("sg-annotations");
if (els.length > 0) {
els[0].appendChild(annotationDiv);
} else {
var annotationsDiv = document.createElement("div");
annotationsDiv.classList.add("sg-annotations");
annotationsDiv.appendChild(annotationDiv);
parentEl.appendChild(annotationsDiv);
}
},
/**
* recursively find the parent of an element to see if it contains the sg-pattern class
* @param {Object} element to check the parent node of
*/
findParent: function(el) {
if (el.parentNode.classList.contains("sg-pattern")) {
return el.parentNode;
} else {
var parentEl = annotationsPattern.findParent(el.parentNode);
}
return parentEl;
},
/**
* toggle the annotation feature on/off
* based on the great MDN docs at https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage
* @param {Object} event info
*/
@ -48,22 +132,81 @@ var annotationsPattern = {
}
if (event.data.commentToggle != undefined) {
annotationsPattern.commentsActive = (event.data.commentToggle == "on") ? true : false;
for (comment in comments.comments) {
var item = comments.comments[comment];
var els = document.querySelectorAll(item.el);
for (var i = 0; i < els.length; ++i) {
if (event.data.commentToggle == "on") {
els[i].classList.add("has-comment");
} else {
els[i].classList.remove("has-comment");
}
// if this is an overlay make sure it's active for the onclick event
annotationsPattern.commentsOverlayActive = false;
annotationsPattern.commentsEmbeddedActive = false;
// see which flag to toggle based on if this is a styleguide or view-all page
var body = document.getElementsByTagName("body");
if ((event.data.commentToggle == "on") && (body[0].classList.contains("pattern-list"))) {
annotationsPattern.commentsEmbeddedActive = true;
} else if (event.data.commentToggle == "on") {
annotationsPattern.commentsOverlayActive = true;
}
// if comments overlay is turned off make sure to remove the has-comment class and pointer
if (!annotationsPattern.commentsOverlayActive) {
var els = document.querySelectorAll(".has-comment");
for (var i = 0; i < els.length; i++) {
els[i].classList.remove("has-comment");
}
}
// if comments embedding is turned off make sure to hide the annotations div
if (!annotationsPattern.commentsEmbeddedActive) {
var els = document.getElementsByClassName("sg-annotations");
for (var i = 0; i < els.length; i++) {
els[i].style.display = "none";
}
}
// if comments overlay is turned on add the has-comment class and pointer
if (annotationsPattern.commentsOverlayActive) {
for (comment in comments.comments) {
var item = comments.comments[comment];
var els = document.querySelectorAll(item.el);
for (var i = 0; i < els.length; i++) {
els[i].classList.add("has-comment");
}
}
} else if (annotationsPattern.commentsEmbeddedActive && !annotationsPattern.commentsEmbedded) {
// if comment embedding is turned on and comments haven't been embedded yet do it
for (comment in comments.comments) {
var item = comments.comments[comment];
var els = document.querySelectorAll(item.el);
for (var i = 0; i < els.length; ++i) {
annotationsPattern.embedComments(els[i],item.title,item.comment);
}
annotationsPattern.commentsEmbedded = true;
}
} else if (annotationsPattern.commentsEmbeddedActive && annotationsPattern.commentsEmbedded) {
// if comment embedding is turned on and comments have been embedded simply display them
var els = document.getElementsByClassName("sg-annotations");
for (var i = 0; i < els.length; ++i) {
els[i].style.display = "block";
}
}
}
}
};
// add the onclick handlers to the elements that have an annotations
annotationsPattern.showComments();
window.addEventListener("message", annotationsPattern.receiveIframeMessage, false);
window.addEventListener("message", annotationsPattern.receiveIframeMessage, false);
// before unloading the iframe make sure any active overlay is turned off/closed
window.onbeforeunload = function() {
var obj = { "commentOverlay": "off" };
var targetOrigin = (window.location.protocol == "file:") ? "*" : window.location.protocol+"//"+window.location.host;
parent.postMessage(obj,targetOrigin);
};

View File

@ -1,7 +1,7 @@
/*!
* Annotations Support for the Viewer - v0.2
* Annotations Support for the Viewer - v0.3
*
* Copyright (c) 2013 Dave Olsen, http://dmolsen.com
* Copyright (c) 2013 Brad Frost, http://bradfrostweb.com & Dave Olsen, http://dmolsen.com
* Licensed under the MIT license
*
*/
@ -15,30 +15,31 @@ var annotationsViewer = {
onReady: function() {
$('body').addClass('comments-ready');
$('#sg-t-annotations').click(function(){
$('#sg-t-annotations').click(function(e) {
e.preventDefault();
annotationsViewer.toggleComments();
return false;
annotationsViewer.commentContainerInit();
});
annotationsViewer.commentContainerInit();
},
toggleComments: function() {
var targetOrigin = (window.location.protocol == "file:") ? "*" : window.location.protocol+"//"+window.location.host;
$('#sg-t-annotations').toggleClass('active');
if (!annotationsViewer.commentsActive) {
annotationsViewer.commentsActive = true;
document.getElementById('sg-viewport').contentWindow.postMessage({ "commentToggle": "on" },targetOrigin);
$('#sg-t-annotations').text('Annotations On');
} else {
annotationsViewer.commentsActive = false;
document.getElementById('sg-viewport').contentWindow.postMessage({ "commentToggle": "off" },targetOrigin);
$('#sg-t-annotations').text('Annotations Off');
annotationsViewer.slideComment(999);
}
@ -47,7 +48,9 @@ var annotationsViewer = {
commentContainerInit: function() {
$('<div id="comment-container" style="display: none;"></div>').html('<a href="#" id="close-comments">Close</a><h2 id="comment-title">Annotation Title</h2><div id="comment-text">Here is some comment text</div>').appendTo('body').css('bottom',-$(document).outerHeight());
if (document.getElementById("comment-container") == undefined) {
$('<div id="comment-container" style="display: none;"></div>').html('<a href="#" id="close-comments">Close</a><h2 id="comment-title">Annotation Title</h2><div id="comment-text">Here is some comment text</div>').appendTo('body').css('bottom',-$(document).outerHeight());
}
if (annotationsViewer.sw < annotationsViewer.breakpoint) {
$('#comment-container').hide();
@ -96,8 +99,12 @@ var annotationsViewer = {
return;
}
if (event.data.title != undefined) {
annotationsViewer.updateComment(event.data.el,event.data.title,event.data.comment);
if (event.data.commentOverlay != undefined) {
if (event.data.commentOverlay == "on") {
annotationsViewer.updateComment(event.data.el,event.data.title,event.data.comment);
} else {
annotationsViewer.slideComment($('#comment-container').outerHeight());
}
}
}
@ -107,6 +114,14 @@ var annotationsViewer = {
$(document).ready(function() { annotationsViewer.onReady(); });
window.addEventListener("message", annotationsViewer.receiveIframeMessage, false);
// make sure if a new pattern or view-all is loaded that comments are turned on as appropriate
$('#sg-viewport').load(function() {
if (annotationsViewer.commentsActive) {
var targetOrigin = (window.location.protocol == "file:") ? "*" : window.location.protocol+"//"+window.location.host;
document.getElementById('sg-viewport').contentWindow.postMessage({ "commentToggle": "on" },targetOrigin);
}
});
// no idea why this has to be outside. there's something funky going on with the JS pattern
$('#sg-view li a').click(function() {
$(this).parent().parent().removeClass('active');