Update livepreview.

Update ace.
Replace pagedown with sundown. Live preview is now able to render markdown identical to regular gollum by leveraging the same library.

Thanks to @kripken for explaining how to best use emscripten for sundown.
This commit is contained in:
bootstraponline
2012-07-03 13:55:08 -06:00
parent 32930cee01
commit 6ff939451c
67 changed files with 807 additions and 1906 deletions
@@ -2,41 +2,45 @@
<html>
<head>
<title>Live Preview</title>
<link rel="stylesheet" type="text/css" href="../css/template.css" />
<link rel="stylesheet" type="text/css" href="css/custom.css" />
<link rel='stylesheet' type='text/css' href='../css/template.css' />
<link rel='stylesheet' type='text/css' href='css/custom.css' />
</head>
<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. -->
<div id="toolpanel" class="toolpanel edit" style="width: 500px; right: 0px; visibility: hidden;">
<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="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 id='toolpanel' class='toolpanel edit' style='width: 500px; right: 0px; visibility: hidden;'>
<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='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 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 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>
<div id='comment'></div>
<div id='darkness'></div>
<script type="text/javascript">
<script type='text/javascript'>
var require = {
paths: {
ace: "js/ace/lib/ace"
ace: 'js/ace/lib/ace'
}
};
</script>
<script src="js/requirejs/require.js" type="text/javascript" charset="utf-8"></script>
<script src="js/pagedown/Markdown.Converter.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/debounce/jquery.ba-throttle-debounce.js" type="text/javascript" charset="utf-8"></script>
<script src="js/livepreview/livepreview.js" type="text/javascript" charset="utf-8"></script>
<script src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript" charset="utf-8"></script>
<script src='js/requirejs/require.js'></script>
<script src='js/jquery/jquery-1.7.2.min.js'></script>
<script src='js/debounce/jquery.ba-throttle-debounce.js'></script>
<script src='js/sundown/sundown_o2.js'></script>
<script src='js/livepreview/livepreview.js'></script>
<script>(function(d,j){
j = d.createElement('script');
j.src = 'https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
(d.head || d.getElementsByTagName('head')[0]).appendChild(j);
}(document));
</script>
</body>
</html>
@@ -92,7 +92,7 @@ exports.multiSelectCommands = [{
bindKey: "esc",
exec: function(editor) { editor.exitMultiSelectMode(); },
readonly: true,
isAvailable: function(editor) {return editor.inMultiSelectMode}
isAvailable: function(editor) {return editor && editor.inMultiSelectMode}
}];
var HashHandler = require("../keyboard/hash_handler").HashHandler;
@@ -97,10 +97,9 @@ exports.init = function() {
}
}
var m = src.match(/^(?:(.*\/)ace\.js)(?:\?|$)/);
if (m) {
scriptUrl = m[1] || m[2];
}
var m = src.match(/^(.*)\/ace(\-\w+)?\.js(\?|$)/);
if (m)
scriptUrl = m[1];
}
if (scriptUrl) {
@@ -50,9 +50,11 @@
.ace_gutter-cell.ace_info {
background-image: url("data:image/gif;base64,R0lGODlhEAAQAMQAAAAAAEFBQVJSUl5eXmRkZGtra39/f4WFhYmJiZGRkaampry8vMPDw8zMzNXV1dzc3OTk5Orq6vDw8P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABQALAAAAAAQABAAAAUuICWOZGmeaBml5XGwFCQSBGyXRSAwtqQIiRuiwIM5BoYVbEFIyGCQoeJGrVptIQA7");
background-repeat: no-repeat;
background-position: 2px center;
}
.ace_dark .ace_gutter-cell.ace_info {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpGRTk5MTVGREIxNDkxMUUxOTc5Q0FFREQyMTNGMjBFQyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpGRTk5MTVGRUIxNDkxMUUxOTc5Q0FFREQyMTNGMjBFQyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkZFOTkxNUZCQjE0OTExRTE5NzlDQUVERDIxM0YyMEVDIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkZFOTkxNUZDQjE0OTExRTE5NzlDQUVERDIxM0YyMEVDIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+SIDkjAAAAJ1JREFUeNpi/P//PwMlgImBQkB7A6qrq/+DMC55FkIGKCoq4pVnpFkgTp069f/+/fv/r1u37r+tre1/kg0A+ptn9uzZYLaRkRHpLvjw4cNXWVlZhufPnzOcO3eOdAO0tbVPAjHDmzdvGA4fPsxIsgGSkpJmv379Ynj37h2DjIyMCMkG3LhxQ/T27dsMampqDHZ2dq/pH41DxwCAAAMAFdc68dUsFZgAAAAASUVORK5CYII=");
}
.ace_editor .ace_sb {
position: absolute;
@@ -246,9 +248,11 @@
background-image: url("data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%00%05%08%06%00%00%00%8Do%26%E5%00%00%004IDATx%DAe%8A%B1%0D%000%0C%C2%F2%2CK%96%BC%D0%8F9%81%88H%E9%D0%0E%96%C0%10%92%3E%02%80%5E%82%E4%A9*-%EEsw%C8%CC%11%EE%96w%D8%DC%E9*Eh%0C%151(%00%00%00%00IEND%AEB%60%82");
background-repeat: no-repeat;
background-position: center 5px;
background-position: center 4px;
border-radius: 3px;
border: 1px solid transparent;
}
.ace_fold-widget.end {
@@ -262,11 +266,8 @@
.ace_fold-widget:hover {
border: 1px solid rgba(0, 0, 0, 0.3);
background-color: rgba(255, 255, 255, 0.2);
-moz-box-shadow:inset 0 1px 1px rgba(255, 255, 255, 0.7);
-moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);
-webkit-box-shadow:inset 0 1px 1px rgba(255, 255, 255, 0.7);
-webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);
box-shadow:inset 0 1px 1px rgba(255, 255, 255, 0.7);
box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);
background-position: center 4px;
}
@@ -274,14 +275,34 @@
.ace_fold-widget:active {
border: 1px solid rgba(0, 0, 0, 0.4);
background-color: rgba(0, 0, 0, 0.05);
-moz-box-shadow:inset 0 1px 1px rgba(255, 255, 255);
-moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);
-webkit-box-shadow:inset 0 1px 1px rgba(255, 255, 255);
-webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);
box-shadow:inset 0 1px 1px rgba(255, 255, 255);
box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);
}
/**
* Dark version for fold widgets
*/
.ace_dark .ace_fold-widget {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC");
}
.ace_dark .ace_fold-widget.end {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==");
}
.ace_dark .ace_fold-widget.closed {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==");
}
.ace_dark .ace_fold-widget:hover {
box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);
background-color: rgba(255, 255, 255, 0.1);
}
.ace_dark .ace_fold-widget:active {
-moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);
-webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);
box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);
}
.ace_fold-widget.invalid {
background-color: #FFB4B4;
border-color: #DE5555;
@@ -94,7 +94,7 @@ function BracketMatch() {
var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
if (!match) {
chr = line.charAt(pos.column);
pos.column++;
pos = {row: pos.row, column: pos.column + 1};
match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
before = false;
}
@@ -123,9 +123,6 @@ function BracketMatch() {
range.cursor = range.start;
}
if (!before)
pos.column--;
return range;
};
@@ -194,7 +191,7 @@ function BracketMatch() {
return null;
};
this.$findClosingBracket = function(bracket, position, typeRe, allowBlankLine) {
this.$findClosingBracket = function(bracket, position, typeRe) {
var closingBracket = this.$brackets[bracket];
var depth = 1;
@@ -239,12 +236,6 @@ function BracketMatch() {
// whose type matches typeRe
do {
token = iterator.stepForward();
if (allowBlankLine) {
// if you've reached the doc end, or, you match a new content line
if (token === null || token.type == "string") {
return {row: iterator.getCurrentTokenRow() + (token === null ? 1 : -1), column: 0};
}
}
} while (token && !typeRe.test(token.type));
if (token == null)
@@ -1772,7 +1772,7 @@ var Editor = function(renderer, session) {
var range = this.session.getBracketRange(cursor);
if (!range) {
range = editor.find({
range = this.find({
needle: /[{}()\[\]]/g,
preventScroll:true,
start: {row: cursor.row, column: cursor.column - 1}
@@ -1787,10 +1787,10 @@ var Editor = function(renderer, session) {
pos = range && range.cursor || pos;
if (pos) {
if (select) {
if (range && range.isEqual(editor.getSelectionRange()))
if (range && range.isEqual(this.getSelectionRange()))
this.clearSelection();
else
this.selection.selectTo(pos.row, pos.column);
this.selection.selectTo(pos.row, pos.column);
} else {
this.clearSelection();
this.moveCursorTo(pos.row, pos.column);
@@ -105,7 +105,7 @@ StateHandler.prototype = {
var bufferObj = {
bufferToUse: bufferToUse,
symbolicName: symbolicName,
symbolicName: symbolicName
};
if (e) {
@@ -73,7 +73,7 @@ var Marker = function(parentEl) {
var html = [];
for ( var key in this.markers) {
for (var key in this.markers) {
var marker = this.markers[key];
if (!marker.range) {
@@ -140,29 +140,25 @@ var Marker = function(parentEl) {
}
};
// Draws a multi line marker, where lines span the full width
this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig, type) {
// Draws a multi line marker, where lines span the full width
this.drawMultiLineMarker = function(stringBuilder, range, clazz, config, type) {
var padding = type === "background" ? 0 : this.$padding;
var layerWidth = layerConfig.width + 2 * this.$padding - padding;
// from selection start to the end of the line
var height = layerConfig.lineHeight;
var width = Math.round(layerWidth - (range.start.column * layerConfig.characterWidth));
var top = this.$getTop(range.start.row, layerConfig);
var left = Math.round(
padding + range.start.column * layerConfig.characterWidth
);
var height = config.lineHeight;
var top = this.$getTop(range.start.row, config);
var left = Math.round(padding + range.start.column * config.characterWidth);
stringBuilder.push(
"<div class='", clazz, " start' style='",
"height:", height, "px;",
"width:", width, "px;",
"right:0;",
"top:", top, "px;",
"left:", left, "px;'></div>"
);
// from start of the last line to the selection end
top = this.$getTop(range.end.row, layerConfig);
width = Math.round(range.end.column * layerConfig.characterWidth);
top = this.$getTop(range.end.row, config);
var width = Math.round(range.end.column * config.characterWidth);
stringBuilder.push(
"<div class='", clazz, "' style='",
@@ -173,15 +169,15 @@ var Marker = function(parentEl) {
);
// all the complete lines
height = (range.end.row - range.start.row - 1) * layerConfig.lineHeight;
height = (range.end.row - range.start.row - 1) * config.lineHeight;
if (height < 0)
return;
top = this.$getTop(range.start.row + 1, layerConfig);
top = this.$getTop(range.start.row + 1, config);
stringBuilder.push(
"<div class='", clazz, "' style='",
"height:", height, "px;",
"width:", layerWidth, "px;",
"right:0;",
"top:", top, "px;",
"left:", padding, "px;'></div>"
);
@@ -131,7 +131,7 @@ var Text = function(parentEl) {
container.appendChild(measureNode);
}
}
// Size and width can be null if the editor is not visible or
// detached from the document
if (!this.element.offsetWidth)
@@ -153,7 +153,7 @@ var Text = function(parentEl) {
return null;
return size;
}
}
: function() {
if (!this.$measureNode) {
var measureNode = this.$measureNode = dom.createElement("div");
@@ -178,7 +178,7 @@ var Text = function(parentEl) {
container.appendChild(measureNode);
}
var rect = this.$measureNode.getBoundingClientRect();
var size = {
@@ -382,7 +382,7 @@ var Text = function(parentEl) {
"lparen": true
};
this.$renderToken = function(stringBuilder, screenColumn, token, value) {
this.$renderToken = function(stringBuilder, screenColumn, token, value) {
var self = this;
var replaceReg = /\t|&|<|( +)|([\u0000-\u0019\u00a0\u1680\u180E\u2000-\u200b\u2028\u2029\u202F\u205F\u3000\uFEFF])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]/g;
var replaceFunc = function(c, a, b, tabIdx, idx4) {
@@ -447,7 +447,7 @@ var Text = function(parentEl) {
"'>"
);
}
for (var i = 0; i < tokens.length; i++) {
var token = tokens[i];
var value = token.value;
@@ -461,12 +461,12 @@ var Text = function(parentEl) {
else {
while (chars + value.length >= splitChars) {
screenColumn = self.$renderToken(
stringBuilder, screenColumn,
stringBuilder, screenColumn,
token, value.substring(0, splitChars - chars)
);
value = value.substring(splitChars - chars);
chars = splitChars;
if (!onlyContents) {
stringBuilder.push("</div>",
"<div class='ace_line' style='height:",
@@ -510,9 +510,9 @@ var Text = function(parentEl) {
};
this.$renderFoldLine = function(stringBuilder, row, tokens, onlyContents) {
var session = this.session,
foldLine = session.getFoldLine(row),
renderTokens = [];
var session = this.session;
var foldLine = session.getFoldLine(row);
var renderTokens = [];
function addTokens(tokens, from, to) {
var idx = 0, col = 0;
@@ -520,16 +520,14 @@ var Text = function(parentEl) {
col += tokens[idx].value.length;
idx++;
if (idx == tokens.length) {
if (idx == tokens.length)
return;
}
}
if (col != from) {
var value = tokens[idx].value.substring(from - col);
// Check if the token value is longer then the from...to spacing.
if (value.length > (to - from)) {
if (value.length > (to - from))
value = value.substring(0, to - from);
}
renderTokens.push({
type: tokens[idx].type,
@@ -540,15 +538,15 @@ var Text = function(parentEl) {
idx += 1;
}
while (col < to) {
while (col < to && idx < tokens.length) {
var value = tokens[idx].value;
if (value.length + col > to) {
value = value.substring(0, to - col);
}
renderTokens.push({
type: tokens[idx].type,
value: value
});
renderTokens.push({
type: tokens[idx].type,
value: value.substring(0, to - col)
});
} else
renderTokens.push(tokens[idx]);
col += value.length;
idx += 1;
}
@@ -556,27 +554,27 @@ var Text = function(parentEl) {
foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) {
if (placeholder) {
renderTokens.push({
renderTokens.push({
type: "fold",
value: placeholder
});
} else {
if (isNewRow)
tokens = this.session.getTokens(row);
tokens = session.getTokens(row);
if (tokens.length)
addTokens(tokens, lastColumn, column);
}
}.bind(this), foldLine.end.row, this.session.getLine(foldLine.end.row).length);
}, foldLine.end.row, this.session.getLine(foldLine.end.row).length);
// TODO: Build a fake splits array!
var splits = this.session.$useWrapMode?this.session.$wrapData[row]:null;
// splits for foldline are stored at its' first row
var splits = this.session.$useWrapMode ? this.session.$wrapData[row] : null;
this.$renderLineCore(stringBuilder, row, renderTokens, splits, onlyContents);
};
this.$useLineGroups = function() {
// For the updateLines function to work correctly, it's important that the
// child nodes of this.element correspond on a 1-to-1 basis to rows in the
// child nodes of this.element correspond on a 1-to-1 basis to rows in the
// document (as distinct from lines on the screen). For sessions that are
// wrapped, this means we need to add a layer to the node hierarchy (tagged
// with the class name ace_line_group).
@@ -227,7 +227,7 @@ exports.addMultiMouseDownListener = function(el, timeouts, eventHandler, callbac
function normalizeCommandKeys(callback, e, keyCode) {
var hashId = 0;
if (useragent.isOpera && useragent.isMac) {
if ((useragent.isOpera && !("KeyboardEvent" in window)) && useragent.isMac) {
hashId = 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0)
| (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0);
} else {
@@ -268,7 +268,7 @@ function normalizeCommandKeys(callback, e, keyCode) {
exports.addCommandKeyListener = function(el, callback) {
var addListener = exports.addListener;
if (useragent.isOldGecko || useragent.isOpera) {
if (useragent.isOldGecko || (useragent.isOpera && !("KeyboardEvent" in window))) {
// Old versions of Gecko aka. Firefox < 4.0 didn't repeat the keydown
// event if the user pressed the key for a longer time. Instead, the
// keydown event was fired once and later on only the keypress event.
@@ -0,0 +1,98 @@
/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Ajax.org Code Editor (ACE).
*
* The Initial Developer of the Original Code is
* Ajax.org B.V.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Spencer <chris.ag.spencer AT googlemail DOT com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
"use strict";
var oop = require("../../lib/oop");
var XmlBehaviour = require("../behaviour/xml").XmlBehaviour;
var CstyleBehaviour = require("./cstyle").CstyleBehaviour;
var TokenIterator = require("../../token_iterator").TokenIterator;
var voidElements = ['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'];
function hasType(token, type) {
var hasType = true;
var typeList = token.type.split('.');
var needleList = type.split('.');
needleList.forEach(function(needle){
if (typeList.indexOf(needle) == -1) {
hasType = false;
return false;
}
});
return hasType;
}
var HtmlBehaviour = function () {
this.inherit(XmlBehaviour); // Get xml behaviour
this.add("autoclosing", "insertion", function (state, action, editor, session, text) {
if (text == '>') {
var position = editor.getCursorPosition();
var iterator = new TokenIterator(session, position.row, position.column);
var token = iterator.getCurrentToken();
var atCursor = false;
if (!token || !hasType(token, 'meta.tag') && !(hasType(token, 'text') && token.value.match('/'))){
do {
token = iterator.stepBackward();
} while (token && (hasType(token, 'string') || hasType(token, 'keyword.operator') || hasType(token, 'entity.attribute-name') || hasType(token, 'text')));
} else {
atCursor = true;
}
if (!token || !hasType(token, 'meta.tag-name') || iterator.stepBackward().value.match('/')) {
return
}
var element = token.value;
if (atCursor){
var element = element.substring(0, position.column - token.start);
}
if (voidElements.indexOf(element) !== -1){
return;
}
return {
text: '>' + '</' + element + '>',
selection: [1, 1]
}
}
});
}
oop.inherits(HtmlBehaviour, XmlBehaviour);
exports.HtmlBehaviour = HtmlBehaviour;
});
@@ -42,34 +42,55 @@ define(function(require, exports, module) {
var oop = require("../../lib/oop");
var Behaviour = require("../behaviour").Behaviour;
var CstyleBehaviour = require("./cstyle").CstyleBehaviour;
var TokenIterator = require("../../token_iterator").TokenIterator;
function hasType(token, type) {
var hasType = true;
var typeList = token.type.split('.');
var needleList = type.split('.');
needleList.forEach(function(needle){
if (typeList.indexOf(needle) == -1) {
hasType = false;
return false;
}
});
return hasType;
}
var XmlBehaviour = function () {
this.inherit(CstyleBehaviour, ["string_dquotes"]); // Get string behaviour
this.add("brackets", "insertion", function (state, action, editor, session, text) {
if (text == '<') {
var selection = editor.getSelectionRange();
var selected = session.doc.getTextRange(selection);
if (selected !== "") {
return false;
this.add("autoclosing", "insertion", function (state, action, editor, session, text) {
if (text == '>') {
var position = editor.getCursorPosition();
var iterator = new TokenIterator(session, position.row, position.column);
var token = iterator.getCurrentToken();
var atCursor = false;
if (!token || !hasType(token, 'meta.tag') && !(hasType(token, 'text') && token.value.match('/'))){
do {
token = iterator.stepBackward();
} while (token && (hasType(token, 'string') || hasType(token, 'keyword.operator') || hasType(token, 'entity.attribute-name') || hasType(token, 'text')));
} else {
return {
text: '<>',
selection: [1, 1]
}
atCursor = true;
}
} else if (text == '>') {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
var rightChar = line.substring(cursor.column, cursor.column + 1);
if (rightChar == '>') { // need some kind of matching check here
return {
text: '',
selection: [1, 1]
}
if (!token || !hasType(token, 'meta.tag-name') || iterator.stepBackward().value.match('/')) {
return
}
} else if (text == "\n") {
var tag = token.value;
if (atCursor){
var tag = tag.substring(0, position.column - token.start);
}
return {
text: '>' + '</' + tag + '>',
selection: [1, 1]
}
}
});
this.add('autoindent', 'insertion', function (state, action, editor, session, text) {
if (text == "\n") {
var cursor = editor.getCursorPosition();
var line = session.doc.getLine(cursor.row);
var rightChars = line.substring(cursor.column, cursor.column + 2);
@@ -56,18 +56,6 @@ oop.inherits(Mode, TextMode);
this.getNextLineIndent = function(state, line, tab) {
var indent = this.$getIndent(line);
// ignore braces in comments
var tokens = this.$tokenizer.getLineTokens(line, state).tokens;
if (tokens.length && tokens[tokens.length-1].type == "comment") {
return indent;
}
var match = line.match(/^.*\{\s*$/);
if (match) {
indent += tab;
}
return indent;
};
@@ -48,7 +48,7 @@ var C9SearchHighlightRules = function() {
this.$rules = {
"start" : [
{
token : ["constant.numeric", "text", "text"],
token : ["c9searchresults.constant.numeric", "c9searchresults.text", "c9searchresults.text"],
regex : "(^\\s+[0-9]+)(:\\s*)(.+)"
},
{
@@ -41,7 +41,7 @@ define(function(require, exports, module) {
var Tokenizer = require("../tokenizer").Tokenizer;
var Rules = require("./coffee_highlight_rules").CoffeeHighlightRules;
var Outdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var PythonFoldMode = require("./folding/pythonic").FoldMode;
var PythonFoldMode = require("./folding/coffee").FoldMode;
var Range = require("../range").Range;
var TextMode = require("./text").Mode;
var WorkerClient = require("../worker/worker_client").WorkerClient;
@@ -153,7 +153,7 @@ define(function(require, exports, module) {
regex : "\\?|\\:|\\,|\\."
}, {
token : "keyword.operator",
regex : "(?:[\\-=]>|[-+*/%<>&|^!?=]=|>>>=?|\\-\\-|\\+\\+|::|&&=|\\|\\|=|<<=|>>=|\\?\\.|\\.{2,3}|\\!)"
regex : "(?:[\\-=]>|[-+*/%<>&|^!?=]=|>>>=?|\\-\\-|\\+\\+|::|&&=|\\|\\|=|<<=|>>=|\\?\\.|\\.{2,3}|[!*+-=><])"
}, {
token : "paren.lparen",
regex : "[({[]"
@@ -19,7 +19,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Fabian Jakobs <fabian AT ajax DOT org>
* Garen J. Torikian <gjtorikian AT gmail DOT com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -48,46 +48,32 @@ oop.inherits(FoldMode, BaseFoldMode);
(function() {
this.foldingStartMarker = /[a-zA-Z](:)\s*$/;
this.foldingStopMarker = /^(\s*)$/;
this.foldingStartMarker = /^(\w.*\:|Searching for.*)$/;
this.foldingStopMarker = /^(\s+|Found.*)$/;
this.getFoldWidgetRange = function(session, foldStyle, row) {
var line = session.getLine(row);
var match = line.match(this.foldingStartMarker);
if (match) {
var i = match.index;
var level1 = /^(Found.*|Searching for.*)$/;
var level2 = /^(\w.*\:|\s*)$/;
var re = level1.test(line) ? level1 : level2;
if (match[1])
return this.openingBracketBlock(session, match[1], row, i, false, true);
var range = session.getCommentFoldRange(row, i + match[0].length);
range.end.column -= 2;
return range;
}
if (foldStyle !== "markbeginend")
return;
var match = line.match(this.foldingStopMarker);
if (match) {
var i = match.index + match[0].length;
if (match[2]) {
var range = session.getCommentFoldRange(row, i);
range.end.column -= 2;
return range;
if (this.foldingStartMarker.test(line)) {
for (var i = row + 1, l = session.getLength(); i < l; i++) {
if (re.test(session.getLine(i)))
break;
}
var end = {row: row, column: i};
var start = session.$findOpeningBracket(match[1], end);
if (!start)
return;
return new Range(row, line.length, i, 0);
}
start.column++;
end.column--;
if (this.foldingStopMarker.test(line)) {
for (var i = row - 1; i >= 0; i--) {
line = session.getLine(i);
if (re.test(line))
break;
}
return Range.fromPoints(start, end);
return new Range(i, line.length, row, 0);
}
};
@@ -0,0 +1,127 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Ajax.org Code Editor (ACE).
*
* The Initial Developer of the Original Code is
* Ajax.org B.V.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Fabian Jakobs <fabian AT ajax DOT org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
"use strict";
var oop = require("../../lib/oop");
var BaseFoldMode = require("./fold_mode").FoldMode;
var Range = require("../../range").Range;
var FoldMode = exports.FoldMode = function() {};
oop.inherits(FoldMode, BaseFoldMode);
(function() {
this.getFoldWidgetRange = function(session, foldStyle, row) {
var range = this.indentationBlock(session, row);
if (range)
return range;
var re = /\S/;
var line = session.getLine(row);
var startLevel = line.search(re);
if (startLevel == -1 || line[startLevel] != "#")
return;
var startColumn = line.length;
var maxRow = session.getLength();
var startRow = row;
var endRow = row;
while (++row < maxRow) {
line = session.getLine(row);
var level = line.search(re);
if (level == -1)
continue;
if (line[level] != "#")
break;
endRow = row;
}
if (endRow > startRow) {
var endColumn = session.getLine(endRow).length;
return new Range(startRow, startColumn, endRow, endColumn);
}
};
// must return "" if there's no fold, to enable caching
this.getFoldWidget = function(session, foldStyle, row) {
var line = session.getLine(row);
var indent = line.search(/\S/);
var next = session.getLine(row + 1);
var prev = session.getLine(row - 1);
var prevIndent = prev.search(/\S/);
var nextIndent = next.search(/\S/);
if (indent == -1) {
session.foldWidgets[row - 1] = prevIndent!= -1 && prevIndent < nextIndent ? "start" : "";
return "";
}
// documentation comments
if (prevIndent == -1) {
if (indent == nextIndent && line[indent] == "#" && next[indent] == "#") {
session.foldWidgets[row - 1] = "";
session.foldWidgets[row + 1] = "";
return "start";
}
} else if (prevIndent == indent && line[indent] == "#" && prev[indent] == "#") {
if (session.getLine(row - 2).search(/\S/) == -1) {
session.foldWidgets[row - 1] = "start";
session.foldWidgets[row + 1] = "";
return ""
}
}
if (prevIndent!= -1 && prevIndent < indent)
session.foldWidgets[row - 1] = "start";
else
session.foldWidgets[row - 1] = "";
if (indent < nextIndent)
return "start";
else
return "";
};
}).call(FoldMode.prototype);
});
@@ -0,0 +1,108 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Ajax.org Code Editor (ACE).
*
* The Initial Developer of the Original Code is
* Ajax.org B.V.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Fabian Jakobs <fabian AT ajax DOT org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
if (typeof process !== "undefined")
require("amd-loader");
define(function(require, exports, module) {
"use strict";
var CoffeeMode = require("../coffee").Mode;
var EditSession = require("../../edit_session").EditSession;
var assert = require("../../test/assertions");
function testFoldWidgets(array) {
var session = array.filter(function(_, i){return i % 2 == 1});
session = new EditSession(session);
var mode = new CoffeeMode();
session.setFoldStyle("markbeginend");
session.setMode(mode);
var widgets = array.filter(function(_, i){return i % 2 == 0});
widgets.forEach(function(w, i){
session.foldWidgets[i] = session.getFoldWidget(i);
})
widgets.forEach(function(w, i){
w = w.split(",");
var type = w[0] == ">" ? "start" : w[0] == "<" ? "end" : "";
assert.equal(session.foldWidgets[i], type);
if (!type)
return;
var range = session.getFoldWidgetRange(i);
if (!w[1]) {
assert.equal(range, null);
return;
}
assert.equal(range.start.row, i);
assert.equal(range.end.row - range.start.row, parseInt(w[1]));
testColumn(w[2], range.start);
testColumn(w[3], range.end);
});
function testColumn(w, pos) {
if (!w)
return;
if (w == "l")
w = session.getLine(pos.row).length;
else
w = parseInt(w);
assert.equal(pos.column, w);
}
}
module.exports = {
"test: coffee script indentation based folding": function() {
testFoldWidgets([
'>,1,l,l', ' ## indented comment',
'', ' # ',
'', '',
'>,1,l,l', ' # plain comment',
'', ' # ',
'>,2', ' function (x)=>',
'', ' ',
'', ' x++',
'', ' ',
'', ' ',
'>,2', ' bar = ',
'', ' foo: 1',
'', ' baz: lighter'
]);
}
};
});
if (typeof module !== "undefined" && module === require.main)
require("asyncjs").test.testcase(module.exports).exec();
@@ -58,25 +58,27 @@ var FoldMode = exports.FoldMode = function() {};
return "end";
return "";
};
this.getFoldWidgetRange = function(session, foldStyle, row) {
return null;
};
this.indentationBlock = function(session, row, column) {
var re = /^\s*/;
var re = /\S/;
var line = session.getLine(row);
var startLevel = line.search(re);
if (startLevel == -1)
return;
var startColumn = column || line.length;
var maxRow = session.getLength();
var startRow = row;
var endRow = row;
var line = session.getLine(row);
var startColumn = column || line.length;
var startLevel = line.match(re)[0].length;
var maxRow = session.getLength()
while (++row < maxRow) {
line = session.getLine(row);
var level = line.match(re)[0].length;
if (level == line.length)
while (++row < maxRow) {
var level = session.getLine(row).search(re);
if (level == -1)
continue;
if (level <= startLevel)
@@ -91,9 +93,9 @@ var FoldMode = exports.FoldMode = function() {};
}
};
this.openingBracketBlock = function(session, bracket, row, column, typeRe, allowBlankLine) {
this.openingBracketBlock = function(session, bracket, row, column, typeRe) {
var start = {row: row, column: column + 1};
var end = session.$findClosingBracket(bracket, start, typeRe, allowBlankLine);
var end = session.$findClosingBracket(bracket, start, typeRe);
if (!end)
return;
@@ -101,7 +103,7 @@ var FoldMode = exports.FoldMode = function() {};
if (fw == null)
fw = this.getFoldWidget(session, end.row);
if (fw == "start") {
if (fw == "start" && end.row > start.row) {
end.row --;
end.column = session.getLine(end.row).length;
}
@@ -42,7 +42,7 @@ var oop = require("../../lib/oop");
var BaseFoldMode = require("./fold_mode").FoldMode;
var FoldMode = exports.FoldMode = function(markers) {
this.foldingStartMarker = new RegExp("(?:([\\[{])|(" + markers + "))(?:\\s*)(?:#.*)?$");
this.foldingStartMarker = new RegExp("([\\[{])(?:\\s*)$|(" + markers + ")(?:\\s*)(?:#.*)?$");
};
oop.inherits(FoldMode, BaseFoldMode);
@@ -49,11 +49,12 @@ module.exports = {
"test: bracket folding": function() {
var session = new EditSession([
'[ #-',
'[ ',
'stuff',
']',
'[ ',
'{ '
'{ ',
'[ #-',
]);
var mode = new PythonMode();
@@ -65,9 +66,11 @@ module.exports = {
assert.equal(session.getFoldWidget(2), "");
assert.equal(session.getFoldWidget(3), "start");
assert.equal(session.getFoldWidget(4), "start");
assert.equal(session.getFoldWidget(5), "");
assert.range(session.getFoldWidgetRange(0), 0, 1, 2, 0);
assert.equal(session.getFoldWidgetRange(3), null);
assert.equal(session.getFoldWidgetRange(5), null);
},
"test: indentation folding": function() {
@@ -44,13 +44,13 @@ var JavaScriptMode = require("./javascript").Mode;
var CssMode = require("./css").Mode;
var Tokenizer = require("../tokenizer").Tokenizer;
var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules;
var XmlBehaviour = require("./behaviour/xml").XmlBehaviour;
var HtmlBehaviour = require("./behaviour/html").HtmlBehaviour;
var HtmlFoldMode = require("./folding/html").FoldMode;
var Mode = function() {
var highlighter = new HtmlHighlightRules();
this.$tokenizer = new Tokenizer(highlighter.getRules());
this.$behaviour = new XmlBehaviour();
this.$behaviour = new HtmlBehaviour();
this.$embeds = highlighter.getEmbeds();
this.createModeDelegates({
@@ -44,6 +44,25 @@ var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScrip
var xmlUtil = require("./xml_util");
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
var tagMap = {
a : 'anchor',
button : 'form',
form : 'form',
img : 'image',
input : 'form',
label : 'form',
script : 'script',
select : 'form',
textarea : 'form',
style : 'style',
table : 'table',
tbody : 'table',
td : 'table',
tfoot : 'table',
th : 'table',
tr : 'table'
};
var HtmlHighlightRules = function() {
// regexp must not have capturing parentheses
@@ -113,9 +132,9 @@ var HtmlHighlightRules = function() {
} ]
};
xmlUtil.tag(this.$rules, "tag", "start");
xmlUtil.tag(this.$rules, "style", "css-start");
xmlUtil.tag(this.$rules, "script", "js-start");
xmlUtil.tag(this.$rules, "tag", "start", tagMap);
xmlUtil.tag(this.$rules, "style", "css-start", tagMap);
xmlUtil.tag(this.$rules, "script", "js-start", tagMap);
this.embedRules(JavaScriptHighlightRules, "js-", [{
token: "comment",
@@ -380,7 +380,7 @@ var JavaScriptHighlightRules = function() {
"function_arguments": [
{
token: "variable.parameter",
regex: identifierRe,
regex: identifierRe
}, {
token: "punctuation.operator",
regex: "[, ]+",
@@ -1,4 +1,4 @@
define(function(require, exports, module) {
define(function(require, exports, module) {
"use strict";
var oop = require("../lib/oop");
@@ -1,4 +1,4 @@
// LuaPage implements the LuaPage markup as described by the Kepler Project's CGILua
// LuaPage implements the LuaPage markup as described by the Kepler Project's CGILua
// documentation: http://keplerproject.github.com/cgilua/manual.html#templates
define(function(require, exports, module) {
"use strict";
@@ -38,16 +38,6 @@
define(function(require, exports, module) {
"use strict";
var lang = require("../lib/lang");
var formTags = lang.arrayToMap(
("button|form|input|label|select|textarea").split("|")
);
var tableTags = lang.arrayToMap(
("table|tbody|td|tfoot|th|tr").split("|")
);
function string(state) {
return [{
token : "string",
@@ -81,7 +71,7 @@ function multiLineString(quote, state) {
}];
}
exports.tag = function(states, name, nextState) {
exports.tag = function(states, name, nextState, tagMap) {
states[name] = [{
token : "text",
regex : "\\s+"
@@ -89,26 +79,10 @@ exports.tag = function(states, name, nextState) {
//token : "meta.tag",
token : function(value) {
if ( value==='a' ) {
return "meta.tag.anchor";
}
else if ( value==='img' ) {
return "meta.tag.image";
}
else if ( value==='script' ) {
return "meta.tag.script";
}
else if ( value==='style' ) {
return "meta.tag.style";
}
else if (formTags.hasOwnProperty(value.toLowerCase())) {
return "meta.tag.form";
}
else if (tableTags.hasOwnProperty(value.toLowerCase())) {
return "meta.tag.table";
}
else {
return "meta.tag";
if (tagMap && tagMap[value]) {
return "meta.tag.tag-name" + '.' + tagMap[value];
} else {
return "meta.tag.tag-name";
}
},
merge : true,
@@ -58,13 +58,10 @@ function GutterHandler(mouseHandler) {
var row = e.getDocumentPosition().row;
var selection = editor.session.selection;
if (e.getShiftKey()) {
if (e.getShiftKey())
selection.selectTo(row, 0);
} else {
selection.moveCursorTo(row, 0);
selection.selectLine();
mouseHandler.$clickSelection = selection.getRange();
}
else
mouseHandler.$clickSelection = editor.selection.getLineRange(row);
mouseHandler.captureMouse(e, "selectByLines");
return e.preventDefault();
@@ -65,7 +65,7 @@ function DefaultHandlers(mouseHandler) {
mouseHandler.selectByLines = this.extendSelectionBy.bind(mouseHandler, "getLineRange");
mouseHandler.selectByWords = this.extendSelectionBy.bind(mouseHandler, "getWordRange");
mouseHandler.$focusWaitTimout = 250;
}
@@ -163,10 +163,12 @@ function DefaultHandlers(mouseHandler) {
if (cmpStart == -1 && cmpEnd <= 0) {
anchor = this.$clickSelection.end;
cursor = range.start;
if (range.end.row != cursor.row || range.end.column != cursor.column)
cursor = range.start;
} else if (cmpEnd == 1 && cmpStart >= 0) {
anchor = this.$clickSelection.start;
cursor = range.end;
if (range.start.row != cursor.row || range.start.column != cursor.column)
cursor = range.end;
} else if (cmpStart == -1 && cmpEnd == 1) {
cursor = range.end;
anchor = range.start;
@@ -286,7 +288,7 @@ function DefaultHandlers(mouseHandler) {
this.setState("select");
return;
}
this.$clickSelection = editor.selection.getWordRange(pos.row, pos.column);
this.setState("selectByWords");
};
@@ -296,10 +298,7 @@ function DefaultHandlers(mouseHandler) {
var editor = this.editor;
this.setState("selectByLines");
editor.moveCursorToPosition(pos);
editor.selection.selectLine();
this.$clickSelection = editor.getSelectionRange();
this.$clickSelection = editor.selection.getLineRange(pos.row);
};
this.onQuadClick = function(ev) {
@@ -345,7 +344,7 @@ function calcRangeOrientation(range, cursor) {
var cmp = 2 * cursor.column - range.start.column - range.end.column;
else
var cmp = 2 * cursor.row - range.start.row - range.end.row;
if (cmp < 0)
return {cursor: range.start, anchor: range.end};
else
@@ -41,17 +41,17 @@
(function() {
var globalRequire = require;
var globalRequire = typeof require != "undefined" && require;
define(function (require, exports, module) {
"use strict";
exports.load = function (name, req, onLoad, config) {
if (req.isBrowser)
require("ace/lib/net").get(req.toUrl(name), onLoad);
//Using special require.nodeRequire, something added by r.js.
if (globalRequire && globalRequire.nodeRequire)
onLoad(('fs').readFileSync(req.toUrl(name), 'utf8'));
else
//Using special require.nodeRequire, something added by r.js.
onLoad(globalRequire.nodeRequire('fs').readFileSync(req.toUrl(name), 'utf8'));
require("ace/lib/net").get(req.toUrl(name), onLoad);
};
});
@@ -42,6 +42,7 @@ var testNames = [
"ace/mode/folding/html_test",
"ace/mode/folding/pythonic_test",
"ace/mode/folding/xml_test",
"ace/mode/folding/coffee_test",
"ace/multi_select_test",
"ace/range_test",
"ace/range_list_test",
@@ -7,7 +7,7 @@
}
.ace-chrome .ace_gutter {
background: #e8e8e8;
background: #ebebeb;
color: #333;
overflow : hidden;
}
@@ -18,7 +18,6 @@
}
.ace-chrome .ace_text-layer {
cursor: text;
}
.ace-chrome .ace_cursor {
@@ -151,7 +150,10 @@ color:#FD971F;
color: rgb(255, 0, 0)
}
.ace-chrome .ace_line .ace_string,
.ace-chrome .ace_line .ace_string{
color: #1A1AA6;
}
.ace-chrome .ace_entity.ace_other.ace_attribute-name{
color: #994409;
}
@@ -8,7 +8,7 @@
}
.ace-clouds .ace_gutter {
background: #e8e8e8;
background: #ebebeb;
color: #333;
}
@@ -22,7 +22,6 @@
}
.ace-clouds .ace_text-layer {
cursor: text;
color: #000000;
}
@@ -8,13 +8,13 @@
}
.ace-clouds-midnight .ace_gutter {
background: #e8e8e8;
color: #333;
background: #232323;
color: #929292;
}
.ace-clouds-midnight .ace_print_margin {
width: 1px;
background: #e8e8e8;
background: #232323;
}
.ace-clouds-midnight .ace_scroller {
@@ -22,7 +22,6 @@
}
.ace-clouds-midnight .ace_text-layer {
cursor: text;
color: #929292;
}
@@ -58,7 +57,7 @@
}
.ace-clouds-midnight .ace_gutter_active_line {
background-color : #dcdcdc;
background-color: rgba(215, 215, 215, 0.031);
}
.ace-clouds-midnight .ace_marker-layer .ace_selected_word {
@@ -8,13 +8,13 @@
}
.ace-cobalt .ace_gutter {
background: #e8e8e8;
color: #333;
background: #011e3a;
color: #fff;
}
.ace-cobalt .ace_print_margin {
width: 1px;
background: #e8e8e8;
background: #011e3a;
}
.ace-cobalt .ace_scroller {
@@ -22,7 +22,6 @@
}
.ace-cobalt .ace_text-layer {
cursor: text;
color: #FFFFFF;
}
@@ -58,7 +57,7 @@
}
.ace-cobalt .ace_gutter_active_line {
background-color : #dcdcdc;
background-color : rgba(0, 0, 0, 0.35);
}
.ace-cobalt .ace_marker-layer .ace_selected_word {
@@ -7,7 +7,7 @@
}
.ace-crimson-editor .ace_gutter {
background: #e8e8e8;
background: #ebebeb;
color: #333;
overflow : hidden;
}
@@ -23,7 +23,6 @@
}
.ace-crimson-editor .ace_text-layer {
cursor: text;
color: rgb(64, 64, 64);
}
@@ -134,6 +133,10 @@
background: rgb(232, 242, 254);
}
.ace-crimson-editor .ace_gutter_active_line {
background-color : #dcdcdc;
}
.ace-crimson-editor .ace_meta.ace_tag {
color:rgb(28, 2, 255);
}
@@ -8,7 +8,7 @@
}
.ace-dawn .ace_gutter {
background: #e8e8e8;
background: #ebebeb;
color: #333;
}
@@ -22,7 +22,6 @@
}
.ace-dawn .ace_text-layer {
cursor: text;
color: #080808;
}
@@ -21,7 +21,6 @@
}
.ace-dreamweaver .ace_text-layer {
cursor: text;
}
.ace-dreamweaver .ace_cursor {
@@ -7,14 +7,14 @@
}
.ace-eclipse .ace_gutter {
background: rgb(227, 227, 227);
background: #ebebeb;
border-right: 1px solid rgb(159, 159, 159);
color: rgb(136, 136, 136);
}
.ace-eclipse .ace_print_margin {
width: 1px;
background: #b1b4ba;
background: #ebebeb;
}
.ace-eclipse .ace_fold {
@@ -22,7 +22,6 @@
}
.ace-eclipse .ace_text-layer {
cursor: text;
}
.ace-eclipse .ace_cursor {
@@ -13,6 +13,15 @@
margin-bottom: 15px;
}
.ace-github .ace_gutter {
background: #e8e8e8;
color: #AAA;
}
.ace-github .ace_scroller {
background: #fff;
}
.ace-github .ace_keyword {
font-weight: bold;
}
@@ -29,6 +38,14 @@
color: #099;
}
.ace-github .ace_constant.ace_buildin {
color: #0086B3;
}
.ace-github .ace_support.ace_function {
color: #0086B3;
}
.ace-github .ace_comment {
color: #998;
font-style: italic;
@@ -38,12 +55,11 @@
color: #0086B3;
}
.ace-github .ace_paren.ace_lparen,
.ace-github .ace_paren.ace_rparen {
.ace-github .ace_paren {
font-weight: bold;
}
.ace-github .ace_constant.ace_language.ace_boolean {
.ace-github .ace_boolean {
font-weight: bold;
}
@@ -61,7 +77,6 @@
}
.ace-github .ace_text-layer {
cursor: text;
}
.ace-github .ace_cursor {
@@ -73,10 +88,46 @@
border-bottom: 1px solid black;
}
.ace-github .ace_marker-layer .ace_active_line {
background: rgb(255, 255, 204);
}
.ace-github .ace_marker-layer .ace_selection {
background: rgb(181, 213, 255);
}
.ace-github.multiselect .ace_selection.start {
box-shadow: 0 0 3px 0px white;
border-radius: 2px;
}
/* bold keywords cause cursor issues for some fonts */
/* this disables bold style for editor and keeps for static highlighter */
.ace-github.ace_editor .ace_line > span {
font-weight: normal !important;
}
.ace-github .ace_marker-layer .ace_step {
background: rgb(252, 255, 0);
}
.ace-github .ace_marker-layer .ace_stack {
background: rgb(164, 229, 101);
}
.ace-github .ace_marker-layer .ace_bracket {
margin: -1px 0 0 -1px;
border: 1px solid rgb(192, 192, 192);
}
.ace-github .ace_gutter_active_line{
background-color : rgba(0, 0, 0, 0.07);
}
.ace-github .ace_marker-layer .ace_selected_word {
background: rgb(250, 250, 255);
border: 1px solid rgb(200, 200, 250);
}
.ace-github .ace_print_margin {
width: 1px;
background: #e8e8e8;
}
@@ -37,7 +37,7 @@
define(function(require, exports, module) {
exports.isDark = true;
exports.isDark = false;
exports.cssClass = "ace-github";
exports.cssText = require('ace/requirejs/text!./github.css');
@@ -8,13 +8,13 @@
}
.ace-idle-fingers .ace_gutter {
background: #e8e8e8;
color: #333;
background: #3b3b3b;
color: #fff;
}
.ace-idle-fingers .ace_print_margin {
width: 1px;
background: #e8e8e8;
background: #3b3b3b;
}
.ace-idle-fingers .ace_scroller {
@@ -22,7 +22,6 @@
}
.ace-idle-fingers .ace_text-layer {
cursor: text;
color: #FFFFFF;
}
@@ -58,7 +57,7 @@
}
.ace-idle-fingers .ace_gutter_active_line {
background-color : #dcdcdc;
background-color: #353637;
}
.ace-idle-fingers .ace_marker-layer .ace_selected_word {
@@ -8,13 +8,13 @@
}
.ace-kr-theme .ace_gutter {
background: #e8e8e8;
color: #333;
background: #1c1917;
color: #FCFFE0;
}
.ace-kr-theme .ace_print_margin {
width: 1px;
background: #e8e8e8;
background: #1c1917;
}
.ace-kr-theme .ace_scroller {
@@ -22,7 +22,6 @@
}
.ace-kr-theme .ace_text-layer {
cursor: text;
color: #FCFFE0;
}
@@ -58,7 +57,7 @@
}
.ace-kr-theme .ace_gutter_active_line {
background-color : #dcdcdc;
background-color : #38403D;
}
.ace-kr-theme .ace_marker-layer .ace_selected_word {
@@ -8,8 +8,8 @@
}
.ace-merbivore .ace_gutter {
background: #e8e8e8;
color: #333;
background: #202020;
color: #E6E1DC;
}
.ace-merbivore .ace_print_margin {
@@ -22,7 +22,6 @@
}
.ace-merbivore .ace_text-layer {
cursor: text;
color: #E6E1DC;
}
@@ -58,7 +57,7 @@
}
.ace-merbivore .ace_gutter_active_line {
background-color : #dcdcdc;
background-color : #333435;
}
.ace-merbivore .ace_marker-layer .ace_selected_word {
@@ -8,13 +8,13 @@
}
.ace-merbivore-soft .ace_gutter {
background: #e8e8e8;
color: #333;
background: #262424;
color: #E6E1DC;
}
.ace-merbivore-soft .ace_print_margin {
width: 1px;
background: #e8e8e8;
background: #262424;
}
.ace-merbivore-soft .ace_scroller {
@@ -22,7 +22,6 @@
}
.ace-merbivore-soft .ace_text-layer {
cursor: text;
color: #E6E1DC;
}
@@ -58,7 +57,7 @@
}
.ace-merbivore-soft .ace_gutter_active_line {
background-color : #dcdcdc;
background-color: #333435;
}
.ace-merbivore-soft .ace_marker-layer .ace_selected_word {
@@ -8,8 +8,8 @@
}
.ace-mono-industrial .ace_gutter {
background: #e8e8e8;
color: #333;
background: #1d2521;
color: #fff;
}
.ace-mono-industrial .ace_print_margin {
@@ -22,7 +22,6 @@
}
.ace-mono-industrial .ace_text-layer {
cursor: text;
color: #FFFFFF;
}
@@ -58,7 +57,7 @@
}
.ace-mono-industrial .ace_gutter_active_line {
background-color : #dcdcdc;
background-color: rgba(12, 13, 12, 0.25);
}
.ace-mono-industrial .ace_marker-layer .ace_selected_word {
@@ -8,7 +8,7 @@
}
.ace-monokai .ace_gutter {
background: #292a24;
background: #2f3129;
color: #f1f1f1;
}
@@ -22,7 +22,6 @@
}
.ace-monokai .ace_text-layer {
cursor: text;
color: #F8F8F2;
}
@@ -8,13 +8,13 @@
}
.ace-pastel-on-dark .ace_gutter {
background: #e8e8e8;
color: #333;
background: #353030;
color: #8F938F;
}
.ace-pastel-on-dark .ace_print_margin {
width: 1px;
background: #e8e8e8;
background: #353030;
}
.ace-pastel-on-dark .ace_scroller {
@@ -22,7 +22,6 @@
}
.ace-pastel-on-dark .ace_text-layer {
cursor: text;
color: #8F938F;
}
@@ -58,7 +57,7 @@
}
.ace-pastel-on-dark .ace_gutter_active_line {
background-color : #dcdcdc;
background-color: rgba(255, 255, 255, 0.031);
}
.ace-pastel-on-dark .ace_marker-layer .ace_selected_word {
@@ -8,7 +8,7 @@
}
.ace-solarized-dark .ace_gutter {
background: #09222b;
background: #01313f;
color: #d0edf7;
}
@@ -22,7 +22,6 @@
}
.ace-solarized-dark .ace_text-layer {
cursor: text;
color: #93A1A1;
}
@@ -8,7 +8,7 @@
}
.ace-solarized-light .ace_gutter {
background: #e8e8e8;
background: #fbf1d3;
color: #333;
}
@@ -22,7 +22,6 @@
}
.ace-solarized-light .ace_text-layer {
cursor: text;
color: #586E75;
}
@@ -7,7 +7,7 @@
}
.ace-tm .ace_gutter {
background: #e8e8e8;
background: #f0f0f0;
color: #333;
}
@@ -21,7 +21,6 @@
}
.ace-tm .ace_text-layer {
cursor: text;
}
.ace-tm .ace_cursor {
@@ -147,7 +146,8 @@
.ace-tm .ace_marker-layer .ace_active_line {
background: rgba(0, 0, 0, 0.07);
}
.ace-tm .ace_gutter_active_line{
.ace-tm .ace_gutter_active_line {
background-color : #dcdcdc;
}
@@ -8,13 +8,13 @@
}
.ace-tomorrow .ace_gutter {
background: #e8e8e8;
color: #333;
background: #f6f6f6;
color: #4D4D4C;
}
.ace-tomorrow .ace_print_margin {
width: 1px;
background: #e8e8e8;
background: #f6f6f6;
}
.ace-tomorrow .ace_scroller {
@@ -22,7 +22,6 @@
}
.ace-tomorrow .ace_text-layer {
cursor: text;
color: #4D4D4C;
}
@@ -8,13 +8,13 @@
}
.ace-tomorrow-night .ace_gutter {
background: #e8e8e8;
color: #333;
background: #25282c;
color: #C5C8C6;
}
.ace-tomorrow-night .ace_print_margin {
width: 1px;
background: #e8e8e8;
background: #25282c;
}
.ace-tomorrow-night .ace_scroller {
@@ -22,7 +22,6 @@
}
.ace-tomorrow-night .ace_text-layer {
cursor: text;
color: #C5C8C6;
}
@@ -58,7 +57,7 @@
}
.ace-tomorrow-night .ace_gutter_active_line {
background-color : #dcdcdc;
background-color: #282A2E;
}
.ace-tomorrow-night .ace_marker-layer .ace_selected_word {
@@ -8,13 +8,13 @@
}
.ace-tomorrow-night-blue .ace_gutter {
background: #022346;
background: #00204b;
color: #7388b5;
}
.ace-tomorrow-night-blue .ace_print_margin {
width: 1px;
background: #e8e8e8;
background: #00204b;
}
.ace-tomorrow-night-blue .ace_scroller {
@@ -22,7 +22,6 @@
}
.ace-tomorrow-night-blue .ace_text-layer {
cursor: text;
color: #FFFFFF;
}
@@ -8,13 +8,13 @@
}
.ace-tomorrow-night-bright .ace_gutter {
background: #e8e8e8;
color: #333;
background: #1a1a1a;
color: #DEDEDE;
}
.ace-tomorrow-night-bright .ace_print_margin {
width: 1px;
background: #e8e8e8;
background: #1a1a1a;
}
.ace-tomorrow-night-bright .ace_scroller {
@@ -22,7 +22,6 @@
}
.ace-tomorrow-night-bright .ace_text-layer {
cursor: text;
color: #DEDEDE;
}
@@ -58,7 +57,7 @@
}
.ace-tomorrow-night-bright .ace_gutter_active_line {
background-color : #dcdcdc;
background-color: #2A2A2A;
}
.ace-tomorrow-night-bright .ace_marker-layer .ace_selected_word {
@@ -8,13 +8,13 @@
}
.ace-tomorrow-night-eighties .ace_gutter {
background: #e8e8e8;
color: #333;
background: #272727;
color: #CCC;
}
.ace-tomorrow-night-eighties .ace_print_margin {
width: 1px;
background: #e8e8e8;
background: #272727;
}
.ace-tomorrow-night-eighties .ace_scroller {
@@ -22,7 +22,6 @@
}
.ace-tomorrow-night-eighties .ace_text-layer {
cursor: text;
color: #CCCCCC;
}
@@ -58,7 +57,7 @@
}
.ace-tomorrow-night-eighties .ace_gutter_active_line {
background-color : #dcdcdc;
background-color: #393939;
}
.ace-tomorrow-night-eighties .ace_marker-layer .ace_selected_word {
@@ -8,13 +8,13 @@
}
.ace-twilight .ace_gutter {
background: #e8e8e8;
color: #333;
background: #232323;
color: #F8F8F8;
}
.ace-twilight .ace_print_margin {
width: 1px;
background: #e8e8e8;
background: #232323;
}
.ace-twilight .ace_scroller {
@@ -22,7 +22,6 @@
}
.ace-twilight .ace_text-layer {
cursor: text;
color: #F8F8F8;
}
@@ -58,7 +57,7 @@
}
.ace-twilight .ace_gutter_active_line {
background-color : #dcdcdc;
background-color: rgba(255, 255, 255, 0.031);
}
.ace-twilight .ace_marker-layer .ace_selected_word {
@@ -8,13 +8,13 @@
}
.ace-vibrant-ink .ace_gutter {
background: #e8e8e8;
color: #333;
background: #1a1a1a;
color: white;
}
.ace-vibrant-ink .ace_print_margin {
width: 1px;
background: #e8e8e8;
background: #1a1a1a;
}
.ace-vibrant-ink .ace_scroller {
@@ -22,7 +22,6 @@
}
.ace-vibrant-ink .ace_text-layer {
cursor: text;
color: #FFFFFF;
}
@@ -58,7 +57,7 @@
}
.ace-vibrant-ink .ace_gutter_active_line {
background-color : #dcdcdc;
background-color: #333333;
}
.ace-vibrant-ink .ace_marker-layer .ace_selected_word {
@@ -263,8 +263,13 @@ var VirtualRenderer = function(container, theme) {
*
* Triggers a full update of all the layers, for all the rows.
**/
this.updateFull = function() {
this.$loop.schedule(this.CHANGE_FULL);
this.updateFull = function(force) {
if (force){
this.$renderChanges(this.CHANGE_FULL, true);
}
else {
this.$loop.schedule(this.CHANGE_FULL);
}
};
/**
@@ -282,11 +287,19 @@ var VirtualRenderer = function(container, theme) {
*
* [Triggers a resize of the editor.]{: #VirtualRenderer.onResize}
**/
this.onResize = function(force) {
this.onResize = function(force, gutterWidth, width, height) {
var changes = this.CHANGE_SIZE;
var size = this.$size;
var height = dom.getInnerHeight(this.container);
if (this.resizing > 2)
return;
else if (this.resizing > 1)
this.resizing++;
else
this.resizing = force ? 1 : 0;
if (!height)
height = dom.getInnerHeight(this.container);
if (force || size.height != height) {
size.height = height;
@@ -300,20 +313,27 @@ var VirtualRenderer = function(container, theme) {
}
}
var width = dom.getInnerWidth(this.container);
if (force || size.width != width) {
if (!width)
width = dom.getInnerWidth(this.container);
if (force || this.resizing > 1 || size.width != width) {
size.width = width;
var gutterWidth = this.showGutter ? this.$gutter.offsetWidth : 0;
this.scroller.style.left = gutterWidth + "px";
size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBar.getWidth());
this.scroller.style.width = size.scrollerWidth + "px";
this.scroller.style.right = this.scrollBar.getWidth() + "px";
if (this.session.getUseWrapMode() && this.adjustWrapLimit() || force)
changes = changes | this.CHANGE_FULL;
}
this.$loop.schedule(changes);
if (force)
this.$renderChanges(changes, true);
else
this.$loop.schedule(changes);
if (force)
delete this.resizing;
};
/**
@@ -642,8 +662,8 @@ var VirtualRenderer = function(container, theme) {
this.scrollBar.setScrollTop(this.scrollTop);
};
this.$renderChanges = function(changes) {
if (!changes || !this.session || !this.container.offsetWidth)
this.$renderChanges = function(changes, force) {
if (!force && (!changes || !this.session || !this.container.offsetWidth))
return;
// text, scrolling and resize changes can cause the view port size to change
@@ -1,6 +1,16 @@
require([ 'ace/ext/static_highlight', 'ace/theme/github', 'ace/editor', 'ace/virtual_renderer', 'ace/mode/markdown', 'ace/theme/twilight',
'ace/mode/c_cpp', 'ace/mode/clojure', 'ace/mode/coffee', 'ace/mode/coldfusion', 'ace/mode/csharp', 'ace/mode/css', 'ace/mode/diff', 'ace/mode/golang', 'ace/mode/groovy', 'ace/mode/haxe', 'ace/mode/html', 'ace/mode/java', 'ace/mode/javascript', 'ace/mode/json', 'ace/mode/latex', 'ace/mode/less', 'ace/mode/liquid', 'ace/mode/lua', 'ace/mode/markdown', 'ace/mode/ocaml', 'ace/mode/perl', 'ace/mode/pgsql', 'ace/mode/php', 'ace/mode/powershell', 'ace/mode/python', 'ace/mode/ruby', 'ace/mode/scad', 'ace/mode/scala', 'ace/mode/scss', 'ace/mode/sh', 'ace/mode/sql', 'ace/mode/svg', 'ace/mode/textile', 'ace/mode/text', 'ace/mode/xml', 'ace/mode/xquery', 'ace/mode/yaml'
], function() {
// Grab functions from emscripten
var Pointer_stringify = Module['Pointer_stringify'];
var _str_to_html = Module['_str_to_html'];
var malloc = Module._malloc;
var realloc = Module._realloc;
var writeStringToMemory = Module.writeStringToMemory;
var allocSize = 1024;
var pointer = malloc( allocSize ) ;
// end emscripten
var Renderer = require( 'ace/virtual_renderer' ).VirtualRenderer;
var Editor = require( 'ace/editor' ).Editor;
var dom = require( 'ace/lib/dom' );
@@ -11,7 +21,6 @@ var doc = document;
win.onbeforeunload = function() { return 'Leaving Live Preview will discard all edits!' };
var converter = Markdown.getSanitizingConverter();
var editor = new Editor( new Renderer( doc.getElementById( 'editor' ) ));//ace.edit( 'editor' );
var editorSession = editor.getSession();
$.editorSession = editorSession; // for testing
@@ -65,13 +74,8 @@ $.key = function( key ) {
// True if &create=true
var create = $.key( 'create' );
// The path and name of the page being edited.
// The name of the page being edited.
var pageName = $.key( 'page' );
var pathName = $.key( 'path' );
if (pathName === 0) {
pathName = undefined;
}
defaultCommitMessage = function() {
var msg = pageName + ' (markdown)';
@@ -93,19 +97,14 @@ $.save = function( commitMessage ) {
var markdown = 'markdown';
var txt = editorSession.getValue();
var msg = defaultCommitMessage();
var newLocation = location.protocol + '//' + location.host;
if (pathName) {
newLocation += '/' + pathName;
}
newLocation += '/' + pageName;
var newLocation = location.protocol + '//' + location.host + '/' + pageName;
// if &create=true then handle create instead of edit.
if ( create ) {
jQuery.ajax( {
type: POST,
url: '/create',
data: { path: pathName, page: pageName, format: markdown, content: txt, message: commitMessage || msg },
data: { page: pageName, format: markdown, content: txt, message: commitMessage || msg },
success: function() {
win.location = newLocation;
}
@@ -114,7 +113,7 @@ $.save = function( commitMessage ) {
jQuery.ajax( {
type: POST,
url: '/edit/' + pageName,
data: { path: pathName, page: pageName, format: markdown, content: txt, message: commitMessage || msg },
data: { format: markdown, content: txt, message: commitMessage || msg },
success: function() {
win.location = newLocation;
}
@@ -227,12 +226,17 @@ function highlight( element, language ) {
var newDiv = doc.createElement('div');
newDiv.innerHTML = color.html;
element.parentNode.replaceChild( newDiv, element );
element.parentNode.parentNode.replaceChild( newDiv, element.parentNode );
}
var makePreviewHtml = function () {
var text = editorSession.getValue();
if ( text == undefined || text == '' ) {
previewSet( '' );
return;
}
if (text && text == oldInputText) {
return; // Input text hasn't changed.
}
@@ -242,7 +246,18 @@ var makePreviewHtml = function () {
var prevTime = new Date().getTime();
text = converter.makeHtml( text );
try {
var textLength = text.length;
while ( textLength > allocSize ) {
allocSize <<= 1; // double
pointer = realloc( pointer, allocSize );
}
writeStringToMemory( text, pointer );
text = Pointer_stringify( _str_to_html( pointer ) );
} catch ( e ) {
console.log( e );
}
// Calculate the processing time of the HTML creation.
// It's used as the delay time in the event listener.
@@ -252,7 +267,8 @@ var makePreviewHtml = function () {
// Update the text using feature detection to support IE.
// preview.innerHTML = text; // this doesn't work on IE.
previewSet( text );
MathJax.Hub.Typeset( content );
// MathJax is loaded asynchronously.
if (typeof MathJax != 'undefined') { MathJax.Hub.Typeset( content ); }
// highlight code blocks.
var codeElements = preview.getElementsByTagName( 'pre' );
@@ -263,50 +279,38 @@ var makePreviewHtml = function () {
for ( var idx = 0; idx < codeElementsLength; idx++ ) {
// highlight removes an element so 0 is always the correct index.
// Skipped tags are not removed so they must be added.
var element = codeElements[ 0 + skipped ];
var element = codeElements[ 0 + skipped ].firstChild;
if ( element == undefined) {
return;
}
var codeHTML = element.innerHTML;
// Only use pre tags marked containing code.
if ( codeHTML[ 0 ] !== '`' )
continue;
if ( codeHTML == undefined) {
return;
}
var txt = codeHTML.split( /\b/ );
// the syntax for code highlighting means all code, even one line, contains newlines.
if ( txt.length > 1 && codeHTML.match( /\n/ ) ) {
var declaredLanguage = txt[ 1 ];
var declaredLanguage = element.className.toLowerCase();
var aceMode = declaredLanguage;
// GitHub supports 'c', 'c++', 'cpp'
// which must trigger the 'c_cpp' mode in Ace.
if ( declaredLanguage === 'cpp' ) {
if ( declaredLanguage === 'c' ||
declaredLanguage === 'c++' ||
declaredLanguage === 'cpp' ) {
aceMode = 'c_cpp';
}
// '`c++'.split( /\b/ )
// ["`", "c", "++"]
if ( declaredLanguage === 'c' ) {
aceMode = 'c_cpp';
if ( txt.length > 2 && txt[ 2 ].substring( 0, 2 ) === '++' ) {
declaredLanguage += '++';
}
}
// txt[0] must be '`'
// txt[0] = '`'; txt[1] = 'ruby'
if ( txt[ 0 ] !== '`' || $.inArray( declaredLanguage, languages ) === -1 ) {
if ( $.inArray( declaredLanguage, languages ) === -1 ) {
// Unsupported language.
skipped++;
element.innerHTML = codeHTML.substring( 1 ).trim();
continue;
}
// length + 1 for the marker character.
element.innerHTML = codeHTML.substring( declaredLanguage.length + 1 ).trim();
// highlight: element
highlight( element, aceMode );
} else {
// Highlighting is not for `code` inline syntax. For example `puts "string"`.
skipped++;
element.innerHTML = codeHTML.substring( 1 ).trim();
}
}
}
@@ -335,7 +339,7 @@ var applyTimeout = function () {
editorSession.setValue( data );
}
});
$( '#save' ).click( function() {
$.save();
});
@@ -388,10 +392,10 @@ var applyTimeout = function () {
var widthFourth = widthHalf / 2;
var height = $( win ).height();
var heightHalf = height / 2;
// height minus 50 so the end of document text doesn't flow off the page.
var editorContainerStyle = 'width:' + widthHalf + 'px;' +
'height:' + (height - 50) + 'px;' +
'height:' + (height - 50) + 'px;' +
'left:' + (leftRight === false ? widthHalf + 'px;' : '0px;') +
'top:' + '40px;'; // use 40px for tool menu
cssSet( editorContainer, editorContainerStyle );
File diff suppressed because it is too large Load Diff
@@ -1,109 +0,0 @@
(function () {
var output, Converter;
if (typeof exports === "object" && typeof require === "function") { // we're in a CommonJS (e.g. Node.js) module
output = exports;
Converter = require("./Markdown.Converter").Converter;
} else {
output = window.Markdown;
Converter = output.Converter;
}
output.getSanitizingConverter = function () {
var converter = new Converter();
converter.hooks.chain("postConversion", sanitizeHtml);
converter.hooks.chain("postConversion", balanceTags);
return converter;
}
function sanitizeHtml(html) {
return html.replace(/<[^>]*>?/gi, sanitizeTag);
}
// (tags that can be opened/closed) | (tags that stand alone)
var basic_tag_whitelist = /^(<\/?(b|blockquote|code|del|dd|dl|dt|em|h1|h2|h3|h4|h5|h6|i|kbd|li|ol|p|pre|s|sup|sub|strong|strike|ul)>|<(br|hr)\s?\/?>)$/i;
// <a href="url..." optional title>|</a>
// Make https:// ftp:// prefix optional so relative links work. <a href="page1">page one</a>
var a_white = /^(<a\shref="(((https?|ftp):\/\/|\/))?[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+"(\stitle="[^"<>]+")?\s?>|<\/a>)$/i;
// <img src="url..." optional width optional height optional alt optional title
var img_white = /^(<img\ssrc="(https?:\/\/|\/)[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+"(\swidth="\d{1,3}")?(\sheight="\d{1,3}")?(\salt="[^"<>]*")?(\stitle="[^"<>]*")?\s?\/?>)$/i;
function sanitizeTag(tag) {
if (tag.match(basic_tag_whitelist) || tag.match(a_white) || tag.match(img_white))
return tag;
else
return "";
}
/// <summary>
/// attempt to balance HTML tags in the html string
/// by removing any unmatched opening or closing tags
/// IMPORTANT: we *assume* HTML has *already* been
/// sanitized and is safe/sane before balancing!
///
/// adapted from CODESNIPPET: A8591DBA-D1D3-11DE-947C-BA5556D89593
/// </summary>
function balanceTags(html) {
if (html == "")
return "";
var re = /<\/?\w+[^>]*(\s|$|>)/g;
// convert everything to lower case; this makes
// our case insensitive comparisons easier
var tags = html.toLowerCase().match(re);
// no HTML tags present? nothing to do; exit now
var tagcount = (tags || []).length;
if (tagcount == 0)
return html;
var tagname, tag;
var ignoredtags = "<p><img><br><li><hr>";
var match;
var tagpaired = [];
var tagremove = [];
var needsRemoval = false;
// loop through matched tags in forward order
for (var ctag = 0; ctag < tagcount; ctag++) {
tagname = tags[ctag].replace(/<\/?(\w+).*/, "$1");
// skip any already paired tags
// and skip tags in our ignore list; assume they're self-closed
if (tagpaired[ctag] || ignoredtags.search("<" + tagname + ">") > -1)
continue;
tag = tags[ctag];
match = -1;
if (!/^<\//.test(tag)) {
// this is an opening tag
// search forwards (next tags), look for closing tags
for (var ntag = ctag + 1; ntag < tagcount; ntag++) {
if (!tagpaired[ntag] && tags[ntag] == "</" + tagname + ">") {
match = ntag;
break;
}
}
}
if (match == -1)
needsRemoval = tagremove[ctag] = true; // mark for removal
else
tagpaired[match] = true; // mark paired
}
if (!needsRemoval)
return html;
// delete all orphaned tags from the string
var ctag = 0;
html = html.replace(re, function (match) {
var res = tagremove[ctag] ? "" : match;
ctag++;
return res;
});
return html;
}
})();
File diff suppressed because one or more lines are too long
@@ -1,32 +0,0 @@
A javascript port of Markdown, as used on Stack Overflow
and the rest of Stack Exchange network.
Largely based on showdown.js by John Fraser (Attacklab).
Original Markdown Copyright (c) 2004-2005 John Gruber
<http://daringfireball.net/projects/markdown/>
Original Showdown code copyright (c) 2007 John Fraser
Modifications and bugfixes (c) 2009 Dana Robinson
Modifications and bugfixes (c) 2009-2011 Stack Exchange Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@@ -0,0 +1,4 @@
License
Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -9,13 +9,24 @@ Uses code/assets from:
0. [jquery](https://github.com/jquery/jquery)
0. [sizzle](https://github.com/jquery/sizzle)
0. [notepages](https://github.com/fivesixty/notepages)
0. [pagedown](https://code.google.com/p/pagedown/)
0. [retina_display_icon_set](http://blog.twg.ca/2010/11/retina-display-icon-set/)
0. [debounce](https://github.com/cowboy/jquery-throttle-debounce)
0. [requirejs](https://github.com/jrburke/requirejs)
0. [emscripten](https://github.com/kripken/emscripten)
0. [sundown](https://github.com/bootstraponline/sundown)
See licenses folder for details.
# Updating gollum
- /public/css/custom.css (not css/gollum/)
- /public/images/*
- /public/js/*
- /public/licenses/*
- /public/index.html
- readme.md
- replace template.css link in index.html
# Dependency Notes
## Ace
@@ -32,20 +43,11 @@ Using jQuery v1.7.2.
- Download latest production version from [jquery.com](http://www.jquery.com).
## Pagedown
The [Pagedown code](https://code.google.com/p/pagedown/source/list) used is from revision `3151a581819f39123b0b5fd1ca9e26cebdcaa873`, May 31, 2012. Markdown.Converter.js has been enhanced to support Gollum style code highlighting. Markdown.Sanitizer.js has been fixed to not remove h4-6.
## Sundown & emscripten
https://code.google.com/p/pagedown/source/detail?r=3151a581819f39123b0b5fd1ca9e26cebdcaa873
- The h4-6 fix has been submitted for upstream inclusion. [#29](https://code.google.com/p/pagedown/issues/detail?id=29)
- livepreview has various additions to pagedown so it can't be replaced by upstream unpatched.
# Updating gollum
- /public/css/custom.css (not css/gollum/)
- /public/images/*
- /public/js/*
- /public/licenses/*
- /public/index.html
- readme.md
- replace template.css link in index.html
- Install emscripten
- src/settings.js must be edited to include _str_to_html in exported functions.
> var EXPORTED_FUNCTIONS = ['_main', '_malloc', '_free', '_str_to_html'];
- Run to_js.sh after checking out the emscripten Sundown repository
- Copy the o2 version into livepreview
- Based on upstrean Sundown [c744346e507e7f905d4b401de78db4404068a43c](https://github.com/tanoku/sundown/commit/c744346e507e7f905d4b401de78db4404068a43c)