Add comment window using Ace that allows user entered commit messages.
Use darkness div to dim the background when the comment window is active. Set CSS in batch to avoid unnecessary reflows. Use debouncing to efficiently resize the window. Eliminate previewSetter in favor of redefining the previewSet function.
This commit is contained in:
@@ -2,7 +2,22 @@ body {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#editor {
|
#darkness {
|
||||||
|
visibility: hidden;
|
||||||
|
position: absolute;
|
||||||
|
left: 0px;
|
||||||
|
top: 0px;
|
||||||
|
background-color: black;
|
||||||
|
opacity: 0.8;
|
||||||
|
z-index: 1001; /* must be > 1000 to overlay ace gutter */
|
||||||
|
}
|
||||||
|
|
||||||
|
#commenttoolpanel {
|
||||||
|
visibility: hidden;
|
||||||
|
z-index: 1002; /* > 1001 to not be hidden by darkness */
|
||||||
|
}
|
||||||
|
|
||||||
|
#comment, #editor {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -10,6 +25,16 @@ body {
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
/* Set font size of both ace editors. */
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set comment to have a higher z-index
|
||||||
|
so editor doesn't display in the background. */
|
||||||
|
|
||||||
|
#comment {
|
||||||
|
visibility: hidden;
|
||||||
|
z-index: 1003; /* > 1002 to not be hidden by toolpanel */
|
||||||
}
|
}
|
||||||
|
|
||||||
#contentframe {
|
#contentframe {
|
||||||
@@ -30,7 +55,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* -- Start from notepag.es -- */
|
/* -- Start from notepag.es -- */
|
||||||
#toolpanel {
|
.toolpanel {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
background: #666;
|
background: #666;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -43,7 +68,7 @@ body {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#toolpanel.edit a.edit {
|
.toolpanel.edit a.edit {
|
||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
/* Make it appear as a link even though save
|
/* Make it appear as a link even though save
|
||||||
doesn't have a href attribute. */
|
doesn't have a href attribute. */
|
||||||
@@ -51,7 +76,7 @@ body {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
#toolpanel a {
|
.toolpanel a {
|
||||||
color: white;
|
color: white;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
margin: 0 5px;
|
margin: 0 5px;
|
||||||
@@ -60,7 +85,7 @@ body {
|
|||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
#toolpanel a img {
|
.toolpanel a img {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 525 B |
@@ -2,7 +2,8 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Live Preview</title>
|
<title>Live Preview</title>
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="../css/template.css" />
|
<!-- change to href="../css/template.css" for production. -->
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/gollum/template.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="css/highlightjs/github.css" />
|
<link rel="stylesheet" type="text/css" href="css/highlightjs/github.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="css/custom.css" />
|
<link rel="stylesheet" type="text/css" href="css/custom.css" />
|
||||||
|
|
||||||
@@ -13,27 +14,40 @@
|
|||||||
<script src="js/pagedown/Markdown.Sanitizer.js" type="text/javascript" charset="utf-8"></script>
|
<script src="js/pagedown/Markdown.Sanitizer.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="js/jquery/jquery-1.7.2.min.js" type="text/javascript" charset="utf-8"></script>
|
<script src="js/jquery/jquery-1.7.2.min.js" type="text/javascript" charset="utf-8"></script>
|
||||||
<script src="js/highlightjs/highlight.pack.js" type="text/javascript" charset="utf-8"></script>
|
<script src="js/highlightjs/highlight.pack.js" type="text/javascript" charset="utf-8"></script>
|
||||||
|
<script src="js/debounce/jquery.ba-throttle-debounce.js" type="text/javascript" charset="utf-8"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="editor"></div>
|
<div id="editor"></div>
|
||||||
|
|
||||||
<div id="previewframe"><div id="contentframe" class="markdown-body"></div></div>
|
<div id="previewframe"><div id="contentframe" class="markdown-body"></div></div>
|
||||||
<!-- tool panel from notepage.es. save & savecomment icons from Retina Display Icon Set -->
|
<!-- tool panel from notepage.es. save & savecomment icons from Retina Display Icon Set. -->
|
||||||
<div id="toolpanel" class="edit" style="width: 500px; right: 0px; ">
|
<div id="toolpanel" class="toolpanel edit" style="width: 500px; right: 0px; ">
|
||||||
<a id="save" class="edit"><img src="images/save_24.png" alt="Save" title="Save"></a>
|
<a id="save" class="edit"><img src="images/save_24.png" alt="save" title="save"></a>
|
||||||
<a id="savecomment" class="edit"><img src="images/savecomment_24.png" alt="Save with comment" title="Save with comment"></a>
|
<a id="savecomment" class="edit"><img src="images/savecomment_24.png" alt="Save with comment" title="Save with comment"></a>
|
||||||
<a id="toggle" class="edit" href="javascript:void(0)" onclick="jsm.toggleLeftRight();"><img src="images/lr_24.png" alt="Toggle left to right" title="Toggle left to right"></a>
|
<a id="toggle" class="edit" href="javascript:void(0)" onclick="jsm.toggleLeftRight();"><img src="images/lr_24.png" alt="Toggle left to right" title="Toggle left to right"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="commenttoolpanel" class="toolpanel edit" style="width: 500px; right: 0px; ">
|
||||||
|
<a id="savecommentconfirm" class="edit"><img src="images/savecomment_24.png" alt="Confirm save with comment" title="Confirm save with comment"></a>
|
||||||
|
<a id="commentcancel" class="edit"><img src="images/cancel_24.png" alt="Cancel save with comment" title="Cancel save with comment"></a>
|
||||||
|
</div>
|
||||||
|
<div id="comment"></div>
|
||||||
|
<div id="darkness"></div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
(function () {
|
(function () {
|
||||||
var converter = Markdown.getSanitizingConverter();
|
var converter = Markdown.getSanitizingConverter();
|
||||||
var editor = ace.edit("editor");
|
var editor = ace.edit("editor");
|
||||||
var editorSession = editor.getSession();
|
var editorSession = editor.getSession();
|
||||||
|
var editorContainer = editor.container;
|
||||||
var preview = document.getElementById("previewframe");
|
var preview = document.getElementById("previewframe");
|
||||||
var content = document.getElementById("contentframe");
|
var content = document.getElementById("contentframe");
|
||||||
var toolPanel = document.getElementById("toolpanel");
|
var toolPanel = document.getElementById("toolpanel");
|
||||||
|
var comment = document.getElementById("comment");
|
||||||
|
var commentToolPanel = document.getElementById("commenttoolpanel");
|
||||||
|
// dim the page
|
||||||
|
var darkness = document.getElementById("darkness");
|
||||||
|
|
||||||
var leftRight = true;
|
var leftRight = true;
|
||||||
var jsm = {}; // JavaScript Markdown
|
var jsm = {}; // JavaScript Markdown
|
||||||
@@ -43,18 +57,29 @@ window.jsm.toggleLeftRight = function() {
|
|||||||
jsm.resize();
|
jsm.resize();
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.setTheme("ace/theme/twilight");
|
|
||||||
var MarkdownMode = require("ace/mode/markdown").Mode;
|
var MarkdownMode = require("ace/mode/markdown").Mode;
|
||||||
|
|
||||||
editorSession.setMode(new MarkdownMode());
|
function initAce(editor, editorSession) {
|
||||||
// Gutter shows line numbers
|
editor.setTheme("ace/theme/twilight");
|
||||||
editor.renderer.setShowGutter(true);
|
editorSession.setMode(new MarkdownMode());
|
||||||
editor.renderer.setHScrollBarAlwaysVisible(false);
|
// Gutter shows line numbers
|
||||||
editorSession.setUseSoftTabs(true);
|
editor.renderer.setShowGutter(true);
|
||||||
editorSession.setTabSize(2);
|
editor.renderer.setHScrollBarAlwaysVisible(false);
|
||||||
editorSession.setUseWrapMode(true);
|
editorSession.setUseSoftTabs(true);
|
||||||
editor.setShowPrintMargin(false);
|
editorSession.setTabSize(2);
|
||||||
editor.setBehavioursEnabled(true);
|
editorSession.setUseWrapMode(true);
|
||||||
|
editor.setShowPrintMargin(false);
|
||||||
|
editor.setBehavioursEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
initAce(editor, editorSession);
|
||||||
|
|
||||||
|
// Setup comment ace.
|
||||||
|
var commentEditor = ace.edit("comment"); // Comment Editor
|
||||||
|
var commentEditorSession = commentEditor.getSession(); // Comment Editor Session
|
||||||
|
var commentEditorContainer = commentEditor.container; // COmment Editor Container
|
||||||
|
|
||||||
|
initAce(commentEditor, commentEditorSession);
|
||||||
|
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
// RegExp from http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript
|
// RegExp from http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript
|
||||||
@@ -72,21 +97,21 @@ window.onload = function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$.save = function() {
|
$.save = function( commitMessage ) {
|
||||||
// if &create=true then handle create instead of edit.
|
// if &create=true then handle create instead of edit.
|
||||||
var create = $.key("create");
|
var create = $.key("create");
|
||||||
var POST = "POST";
|
var POST = "POST";
|
||||||
var pageName = $.key("page");
|
var pageName = $.key("page");
|
||||||
var markdown = "markdown";
|
var markdown = "markdown";
|
||||||
var txt = editorSession.getValue();
|
var txt = editorSession.getValue();
|
||||||
var msg = pageName + " ("+markdown+")"
|
var msg = pageName + " (" + markdown + ")"
|
||||||
var newLocation = window.location.origin + "/" + pageName;
|
var newLocation = window.location.origin + "/" + pageName;
|
||||||
|
|
||||||
if (create) {
|
if (create) {
|
||||||
jQuery.ajax({
|
jQuery.ajax({
|
||||||
type: POST,
|
type: POST,
|
||||||
url: "/create",
|
url: "/create",
|
||||||
data: { page: pageName, format: markdown, content: txt, message: "Created " + msg },
|
data: { page: pageName, format: markdown, content: txt, message: commitMessage || "Created " + msg },
|
||||||
success: function() {
|
success: function() {
|
||||||
window.location = newLocation;
|
window.location = newLocation;
|
||||||
}
|
}
|
||||||
@@ -95,7 +120,7 @@ window.onload = function() {
|
|||||||
jQuery.ajax({
|
jQuery.ajax({
|
||||||
type: POST,
|
type: POST,
|
||||||
url: "/edit/" + pageName,
|
url: "/edit/" + pageName,
|
||||||
data: { format: markdown, content: txt, message: "Updated " + msg },
|
data: { format: markdown, content: txt, message: commitMessage || "Updated " + msg },
|
||||||
success: function() {
|
success: function() {
|
||||||
window.location = newLocation;
|
window.location = newLocation;
|
||||||
}
|
}
|
||||||
@@ -103,12 +128,35 @@ window.onload = function() {
|
|||||||
} // end else
|
} // end else
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#save').click(function() {
|
$("#save").click(function() {
|
||||||
$.save();
|
$.save();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#savecomment').click(function() {
|
// Hide dimmer, comment tool panel, and comment.
|
||||||
$.save();
|
$("#commentcancel").click(function() {
|
||||||
|
hideCommentWindow();
|
||||||
|
});
|
||||||
|
|
||||||
|
var isCommentHidden = true;
|
||||||
|
|
||||||
|
function hideCommentWindow() {
|
||||||
|
isCommentHidden = true;
|
||||||
|
darkness.style.visibility = "hidden";
|
||||||
|
commentToolPanel.style.visibility = "hidden";
|
||||||
|
comment.style.visibility = "hidden";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show dimmer, comment tool panel, and comment.
|
||||||
|
$("#savecomment").click(function() {
|
||||||
|
isCommentHidden = false;
|
||||||
|
darkness.style.visibility = "visible";
|
||||||
|
commentToolPanel.style.visibility = "visible";
|
||||||
|
comment.style.visibility = "visible";
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#savecommentconfirm").click(function() {
|
||||||
|
$.save(ces.getValue());
|
||||||
|
hideCommentWindow();
|
||||||
});
|
});
|
||||||
|
|
||||||
// onChange calls applyTimeout which rate limits the calling of makePreviewHtml based on render time.
|
// onChange calls applyTimeout which rate limits the calling of makePreviewHtml based on render time.
|
||||||
@@ -116,33 +164,68 @@ window.onload = function() {
|
|||||||
makePreviewHtml(); // preview default text on load
|
makePreviewHtml(); // preview default text on load
|
||||||
|
|
||||||
function resize() {
|
function resize() {
|
||||||
var ace = editor.container;//document.getElementById("editor");
|
var width = $(window).width();
|
||||||
var widthHalf = $(window).width() / 2;
|
var widthHalf = width / 2;
|
||||||
|
var widthFourth = widthHalf / 2;
|
||||||
var height = $(window).height();
|
var height = $(window).height();
|
||||||
ace.style.width = widthHalf + "px";
|
var heightHalf = height / 2;
|
||||||
// Minus 50 so the end of document text doesn't flow off the page.
|
|
||||||
ace.style.height = height - 50 + "px";
|
// height minus 50 so the end of document text doesn't flow off the page.
|
||||||
ace.style.left = leftRight === false ? widthHalf + "px" : "0px";
|
var editorContainerStyle = "width:" + widthHalf + "px;" +
|
||||||
ace.style.top = "40px"; // use 40px for tool menu
|
"height:" + (height - 50) + "px;" +
|
||||||
ace.style.fontSize = 16 + "px";
|
"left:" + (leftRight === false ? widthHalf + "px;" : "0px;") +
|
||||||
|
"top:" + "40px;"; // use 40px for tool menu
|
||||||
|
cssSet( editorContainer, editorContainerStyle );
|
||||||
editor.resize();
|
editor.resize();
|
||||||
|
|
||||||
var previewFrame = document.getElementById("previewframe");
|
// width -2 for scroll bar & -10 for left offset
|
||||||
previewFrame.style.width = widthHalf - 2 - 10 + "px"; // -2 for scroll bar & -10 for left offset
|
var previewStyle = "width:" + (widthHalf - 2 - 10) + "px;" +
|
||||||
previewFrame.style.height = height + "px";
|
"height:" + height + "px;" +
|
||||||
previewFrame.style.left = leftRight === false ? "10px" : widthHalf + "px";
|
"left:" + (leftRight === false ? "10px;" : widthHalf + "px;") +
|
||||||
previewFrame.style.top = "0px";
|
"top:" + "0px;";
|
||||||
|
cssSet( preview, previewStyle );
|
||||||
|
|
||||||
// Resize tool panel
|
// Resize tool panel
|
||||||
toolPanel.style.width = widthHalf + "px";
|
var toolPanelStyle = "width:" + widthHalf + "px;" +
|
||||||
toolPanel.style.left = leftRight === false ? widthHalf + "px" : "0px";
|
"left:" + (leftRight === false ? widthHalf + "px;" : "0px;");
|
||||||
|
cssSet( toolPanel, toolPanelStyle );
|
||||||
|
|
||||||
|
// Resize comment related elements.
|
||||||
|
var commentHidden = "visibility:" + ( isCommentHidden === true ? "hidden;" : "visible;" );
|
||||||
|
|
||||||
|
// Adjust comment editor
|
||||||
|
var commentEditorContainerStyle = "height:" + heightHalf + "px;" +
|
||||||
|
"width:" + widthHalf + "px;" +
|
||||||
|
"left:" + widthFourth + "px;" +
|
||||||
|
"top:" + (heightHalf / 2) + "px;" +
|
||||||
|
commentHidden;
|
||||||
|
cssSet( commentEditorContainer, commentEditorContainerStyle );
|
||||||
|
commentEditor.resize();
|
||||||
|
|
||||||
|
// In top subtract height (40px) of comment tool panel.
|
||||||
|
var commentToolPanelStyle = "width:" + widthHalf + "px;" +
|
||||||
|
"left:" + widthFourth + "px;" +
|
||||||
|
"top:" + (height / 4 - 40) + "px;" +
|
||||||
|
commentHidden;
|
||||||
|
cssSet( commentToolPanel, commentToolPanelStyle );
|
||||||
|
|
||||||
|
// Resize dimmer.
|
||||||
|
var darknessStyle = "width:" + width + "px;" +
|
||||||
|
"height:" + height + "px;" +
|
||||||
|
commentHidden;
|
||||||
|
cssSet(darkness, darknessStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.jsm.resize = resize;
|
window.jsm.resize = resize;
|
||||||
|
|
||||||
$(window).resize(function() {
|
/*
|
||||||
resize();
|
Resize can be called an absurd amount of times
|
||||||
});
|
and will crash the page without debouncing.
|
||||||
|
http://benalman.com/projects/jquery-throttle-debounce-plugin/
|
||||||
|
https://github.com/cowboy/jquery-throttle-debounce
|
||||||
|
http://unscriptable.com/2009/03/20/debouncing-javascript-methods/
|
||||||
|
*/
|
||||||
|
$(window).resize( $.debounce( 100, resize ) );
|
||||||
|
|
||||||
// resize for the intial page load
|
// resize for the intial page load
|
||||||
resize();
|
resize();
|
||||||
@@ -152,7 +235,6 @@ var elapsedTime;
|
|||||||
var oldInputText = "";
|
var oldInputText = "";
|
||||||
|
|
||||||
// ---- from Markdown.Editor
|
// ---- from Markdown.Editor
|
||||||
var previewSetter;
|
|
||||||
var timeout;
|
var timeout;
|
||||||
|
|
||||||
var nonSuckyBrowserPreviewSet = function (text) {
|
var nonSuckyBrowserPreviewSet = function (text) {
|
||||||
@@ -173,16 +255,39 @@ var ieSafePreviewSet = function (text) {
|
|||||||
parent.insertBefore(content, sibling);
|
parent.insertBefore(content, sibling);
|
||||||
}
|
}
|
||||||
|
|
||||||
var previewSet = function (text) {
|
var cssTextSet = function( element, css ){
|
||||||
if (previewSetter)
|
element.style.cssText = css;
|
||||||
return previewSetter(text);
|
}
|
||||||
|
|
||||||
|
var cssAttrSet = function( element, css ){
|
||||||
|
element.setAttribute( 'style', css );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Redefine the function based on browser support.
|
||||||
|
element - the element to set the css on
|
||||||
|
css - a fully formed css string. ex: "top: 0; left: 0;"
|
||||||
|
|
||||||
|
Avoid reflow by batching CSS changes.
|
||||||
|
http://dev.opera.com/articles/view/efficient-javascript/?page=3#stylechanges
|
||||||
|
*/
|
||||||
|
var cssSet = function( element, css ) {
|
||||||
|
if( typeof( element.style.cssText ) != 'undefined' ) {
|
||||||
|
cssTextSet( element, css );
|
||||||
|
cssSet = cssTextSet;
|
||||||
|
} else {
|
||||||
|
cssAttrSet( element, css );
|
||||||
|
cssSet = cssAttrSet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var previewSet = function( text ) {
|
||||||
try {
|
try {
|
||||||
nonSuckyBrowserPreviewSet(text);
|
nonSuckyBrowserPreviewSet( text );
|
||||||
previewSetter = nonSuckyBrowserPreviewSet;
|
previewSet = nonSuckyBrowserPreviewSet;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
previewSetter = ieSafePreviewSet;
|
ieSafePreviewSet( text );
|
||||||
previewSetter(text);
|
previewSet = ieSafePreviewSet;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user