Scroll Link feature
This commit is contained in:
parent
ff6ee6be4e
commit
b16d6cc7d1
@ -1 +1 @@
|
|||||||
CACHE MANIFEST
# v11
CACHE:
index.html
css/main-min.css
js/main-min.js
js/require.js
img/ajax-loader.gif
img/glyphicons-halflings.png
img/glyphicons-halflings-white.png
img/icons.png
img/stackedit-32.ico
img/stackedit-promo.png
NETWORK:
*
|
CACHE MANIFEST
# v12
CACHE:
index.html
css/main-min.css
js/main-min.js
js/require.js
img/ajax-loader.gif
img/glyphicons-halflings.png
img/glyphicons-halflings-white.png
img/icons.png
img/stackedit-32.ico
img/stackedit-promo.png
NETWORK:
*
|
||||||
|
18
css/main-min.css
vendored
18
css/main-min.css
vendored
@ -5473,7 +5473,7 @@ hr {
|
|||||||
#wmd-input,#wmd-preview {
|
#wmd-input,#wmd-preview {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
#wmd-input {
|
#wmd-input, #md-section-helper {
|
||||||
font-family: "Courier New", Courier, monospace;
|
font-family: "Courier New", Courier, monospace;
|
||||||
resize: none;
|
resize: none;
|
||||||
border: none !important;
|
border: none !important;
|
||||||
@ -5656,4 +5656,20 @@ blockquote p {
|
|||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
#md-section-helper {
|
||||||
|
position: absolute;
|
||||||
|
top: -100px;
|
||||||
|
height: 1px;
|
||||||
|
padding: 0 6px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
.gecko #md-section-helper {
|
||||||
|
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
.opera #md-section-helper {
|
||||||
|
|
||||||
|
top: 0;
|
||||||
}
|
}
|
21
css/main.css
21
css/main.css
@ -162,7 +162,7 @@ hr {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
#wmd-input {
|
#wmd-input, #md-section-helper {
|
||||||
font-family: "Courier New", Courier, monospace;
|
font-family: "Courier New", Courier, monospace;
|
||||||
resize: none;
|
resize: none;
|
||||||
border: none !important;
|
border: none !important;
|
||||||
@ -384,4 +384,23 @@ blockquote p {
|
|||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#md-section-helper {
|
||||||
|
position: absolute;
|
||||||
|
top: -100px;
|
||||||
|
height: 1px;
|
||||||
|
padding: 0 6px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gecko #md-section-helper {
|
||||||
|
/* Firefox doesn't show the scrollbar if height is less than 40px */
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.opera #md-section-helper {
|
||||||
|
/* Opera needs to have the textarea in the viewport to evaluate size correctly */
|
||||||
|
top: 0;
|
||||||
}
|
}
|
21
index.html
21
index.html
@ -11,13 +11,15 @@
|
|||||||
content="StackEdit is a free, open-source Markdown editor based on PageDown, the Markdown library used by Stack Overflow and the other Stack Exchange sites.">
|
content="StackEdit is a free, open-source Markdown editor based on PageDown, the Markdown library used by Stack Overflow and the other Stack Exchange sites.">
|
||||||
<meta name="author" content="Benoit Schweblin">
|
<meta name="author" content="Benoit Schweblin">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link href="css/main-min.css" rel="stylesheet" media="screen">
|
|
||||||
<script>
|
<script>
|
||||||
// http://.../?debug to serve original JavaScript files for debug
|
// http://.../?debug to serve original CSS/JavaScript files for debug
|
||||||
var dep = "main-min";
|
var dep = "main-min";
|
||||||
|
var css = "css/main-min.css";
|
||||||
if (location.search.indexOf("debug") !== -1) {
|
if (location.search.indexOf("debug") !== -1) {
|
||||||
dep = "main";
|
dep = "main";
|
||||||
|
css = "css/main.css";
|
||||||
}
|
}
|
||||||
|
document.write('<link href="' + css + '" rel="stylesheet" media="screen">');
|
||||||
var require = { baseUrl : "js", deps : [ dep ] };
|
var require = { baseUrl : "js", deps : [ dep ] };
|
||||||
</script>
|
</script>
|
||||||
<script src="js/require.js"></script>
|
<script src="js/require.js"></script>
|
||||||
@ -432,6 +434,13 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label" for="input-settings-scroll-link">Scroll Link <a
|
||||||
|
href="#" class="tooltip-scroll-link">(?)</a></label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="checkbox" id="input-settings-scroll-link" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label" for="input-settings-converter-type">Converter</label>
|
<label class="control-label" for="input-settings-converter-type">Converter</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
@ -528,7 +537,10 @@
|
|||||||
<dl>
|
<dl>
|
||||||
<dt>Credit:</dt>
|
<dt>Credit:</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<a target="_blank" href="http://twitter.github.com/bootstrap/">Bootstrap</a>
|
<a target="_blank" href="http://twitter.github.io/bootstrap/">Bootstrap</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a target="_blank" href="https://github.com/rafaelp/css_browser_selector/">CSS Browser Selector</a>
|
||||||
</dd>
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a target="_blank" href="https://github.com/dropbox/dropbox-js">Dropbox-js</a>
|
<a target="_blank" href="https://github.com/dropbox/dropbox-js">Dropbox-js</a>
|
||||||
@ -594,7 +606,8 @@
|
|||||||
class="btn btn-primary">Reload</a>
|
class="btn btn-primary">Reload</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<textarea id="md-section-helper"></textarea>
|
||||||
<div id="dropboxjs" data-app-key="x0k2l8puemfvg0o"></div>
|
<div id="dropboxjs" data-app-key="x0k2l8puemfvg0o"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -17,15 +17,15 @@
|
|||||||
|
|
||||||
// patch for ie7
|
// patch for ie7
|
||||||
if (!Array.indexOf) {
|
if (!Array.indexOf) {
|
||||||
Array.prototype.indexOf = function(obj){
|
Array.prototype.indexOf = function(obj) {
|
||||||
for(var i = 0; i < this.length; i++){
|
for (var i = 0; i < this.length; i++) {
|
||||||
if(this[i] == obj){
|
if (this[i] == obj) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function trim(str) {
|
function trim(str) {
|
||||||
return str.replace(/^\s+|\s+$/g, '');
|
return str.replace(/^\s+|\s+$/g, '');
|
||||||
@ -262,10 +262,10 @@
|
|||||||
// TODO: use sentinels. Should we just add/remove them in doConversion?
|
// TODO: use sentinels. Should we just add/remove them in doConversion?
|
||||||
// TODO: better matches for id / class attributes
|
// TODO: better matches for id / class attributes
|
||||||
var attrBlock = "\\{\\s*[.|#][^}]+\\}";
|
var attrBlock = "\\{\\s*[.|#][^}]+\\}";
|
||||||
var hdrAttributesA = new RegExp("^(#{1,6}.*#{0,6})\\s+(" + attrBlock + ")\\s*(\\n|0x03)", "gm");
|
var hdrAttributesA = new RegExp("^(#{1,6}.*#{0,6})\\s+(" + attrBlock + ")[ \\t]*(\\n|0x03)", "gm");
|
||||||
var hdrAttributesB = new RegExp("^(.*)\\s+(" + attrBlock + ")\\s*\\n" +
|
var hdrAttributesB = new RegExp("^(.*)\\s+(" + attrBlock + ")[ \\t]*\\n" +
|
||||||
"(?=[\\-|=]+\\s*(\\n|0x03))", "gm"); // underline lookahead
|
"(?=[\\-|=]+\\s*(\\n|0x03))", "gm"); // underline lookahead
|
||||||
var fcbAttributes = new RegExp("^(```[^{]*)\\s+(" + attrBlock + ")\\s*\\n" +
|
var fcbAttributes = new RegExp("^(```[^{]*)\\s+(" + attrBlock + ")[ \\t]*\\n" +
|
||||||
"(?=([\\s\\S]*?)\\n```\\s*(\\n|0x03))", "gm");
|
"(?=([\\s\\S]*?)\\n```\\s*(\\n|0x03))", "gm");
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
@ -281,7 +281,7 @@
|
|||||||
Markdown.Extra.prototype.applyAttributeBlocks = function(text) {
|
Markdown.Extra.prototype.applyAttributeBlocks = function(text) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var blockRe = new RegExp('<p>~XX(\\d+)XX</p>[\\s]*' +
|
var blockRe = new RegExp('<p>~XX(\\d+)XX</p>[\\s]*' +
|
||||||
'(?:<(h[1-6]|pre)(?: +class="(\\S+)")?(>[\\s\\S]*</\\2>))', "gm");
|
'(?:<(h[1-6]|pre)(?: +class="(\\S+)")?(>[\\s\\S]*?</\\2>))', "gm");
|
||||||
text = text.replace(blockRe, function(wholeMatch, k, tag, cls, rest) {
|
text = text.replace(blockRe, function(wholeMatch, k, tag, cls, rest) {
|
||||||
if (!tag) // no following header or fenced code block.
|
if (!tag) // no following header or fenced code block.
|
||||||
return '';
|
return '';
|
||||||
|
196
js/core.js
196
js/core.js
@ -1,6 +1,6 @@
|
|||||||
define(
|
define(
|
||||||
[ "jquery", "bootstrap", "jgrowl", "layout", "Markdown.Editor", "config",
|
[ "jquery", "bootstrap", "jgrowl", "layout", "Markdown.Editor", "config",
|
||||||
"underscore", "FileSaver" ],
|
"underscore", "FileSaver", "css_browser_selector" ],
|
||||||
function($) {
|
function($) {
|
||||||
|
|
||||||
var core = {};
|
var core = {};
|
||||||
@ -208,6 +208,7 @@ define(
|
|||||||
core.settings = {
|
core.settings = {
|
||||||
converterType : "markdown-extra-prettify",
|
converterType : "markdown-extra-prettify",
|
||||||
layoutOrientation : "horizontal",
|
layoutOrientation : "horizontal",
|
||||||
|
scrollLink : true,
|
||||||
editorFontSize : 14,
|
editorFontSize : 14,
|
||||||
commitMsg : "Published by StackEdit",
|
commitMsg : "Published by StackEdit",
|
||||||
template : ['<!DOCTYPE html>\n',
|
template : ['<!DOCTYPE html>\n',
|
||||||
@ -228,6 +229,9 @@ define(
|
|||||||
$("input:radio[name=radio-layout-orientation][value="
|
$("input:radio[name=radio-layout-orientation][value="
|
||||||
+ core.settings.layoutOrientation + "]").prop("checked", true);
|
+ core.settings.layoutOrientation + "]").prop("checked", true);
|
||||||
|
|
||||||
|
// Scroll Link
|
||||||
|
$("#input-settings-scroll-link").prop("checked", core.settings.scrollLink);
|
||||||
|
|
||||||
// Converter type
|
// Converter type
|
||||||
$("#input-settings-converter-type").val(core.settings.converterType);
|
$("#input-settings-converter-type").val(core.settings.converterType);
|
||||||
|
|
||||||
@ -251,6 +255,9 @@ define(
|
|||||||
// Converter type
|
// Converter type
|
||||||
newSettings.converterType = $("#input-settings-converter-type").val();
|
newSettings.converterType = $("#input-settings-converter-type").val();
|
||||||
|
|
||||||
|
// Scroll Link
|
||||||
|
newSettings.scrollLink = $("#input-settings-scroll-link").prop("checked");
|
||||||
|
|
||||||
// Editor font size
|
// Editor font size
|
||||||
newSettings.editorFontSize = core.getInputIntValue($("#input-settings-editor-font-size"), event, 1, 99);
|
newSettings.editorFontSize = core.getInputIntValue($("#input-settings-editor-font-size"), event, 1, 99);
|
||||||
|
|
||||||
@ -266,6 +273,131 @@ define(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Used by Scroll Link feature
|
||||||
|
var mdSectionList = [];
|
||||||
|
var htmlSectionList = [];
|
||||||
|
function pxToFloat(px) {
|
||||||
|
return parseFloat(px.substring(0, px.length-2));
|
||||||
|
}
|
||||||
|
var buildSections = _.debounce(function() {
|
||||||
|
|
||||||
|
// Try to find Markdown sections by looking for titles
|
||||||
|
var editorElt = $("#wmd-input");
|
||||||
|
mdSectionList = [];
|
||||||
|
// This textarea is used to measure sections height
|
||||||
|
var textareaElt = $("#md-section-helper");
|
||||||
|
// It has to be the same width than wmd-input
|
||||||
|
textareaElt.width(editorElt.width());
|
||||||
|
// Consider wmd-input top padding
|
||||||
|
var padding = pxToFloat(editorElt.css('padding-top'));
|
||||||
|
var offset = 0, mdSectionOffset = 0;
|
||||||
|
function addMdSection(sectionText) {
|
||||||
|
var sectionHeight = padding;
|
||||||
|
if(sectionText) {
|
||||||
|
textareaElt.val(sectionText);
|
||||||
|
sectionHeight += textareaElt.prop('scrollHeight');
|
||||||
|
}
|
||||||
|
var newSectionOffset = mdSectionOffset + sectionHeight;
|
||||||
|
mdSectionList.push({
|
||||||
|
startOffset: mdSectionOffset,
|
||||||
|
endOffset: newSectionOffset,
|
||||||
|
height: sectionHeight
|
||||||
|
});
|
||||||
|
mdSectionOffset = newSectionOffset;
|
||||||
|
padding = 0;
|
||||||
|
}
|
||||||
|
// Create MD sections by finding title patterns (excluding gfm blocs)
|
||||||
|
var text = editorElt.val() + "\n\n";
|
||||||
|
text.replace(/^```.*\n[\s\S]*?\n```|(^.+[ \t]*\n=+[ \t]*\n+|^.+[ \t]*\n-+[ \t]*\n+|^\#{1,6}[ \t]*.+?[ \t]*\#*\n+)/gm,
|
||||||
|
function(match, title, matchOffset) {
|
||||||
|
if(title) {
|
||||||
|
// We just found a title which means end of the previous section
|
||||||
|
// Exclude last \n of the section
|
||||||
|
addMdSection(text.substring(offset, matchOffset-1));
|
||||||
|
offset = matchOffset;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// Last section
|
||||||
|
// Consider wmd-input bottom padding and exclude \n\n previously added
|
||||||
|
padding += pxToFloat(editorElt.css('padding-bottom'));
|
||||||
|
addMdSection(text.substring(offset, text.length-2));
|
||||||
|
|
||||||
|
// Try to find corresponding sections in the preview
|
||||||
|
var previewElt = $("#wmd-preview");
|
||||||
|
htmlSectionList = [];
|
||||||
|
var htmlSectionOffset = 0;
|
||||||
|
var previewScrollTop = previewElt.scrollTop();
|
||||||
|
// Each title element is a section separator
|
||||||
|
previewElt.children("h1,h2,h3,h4,h5,h6").each(function() {
|
||||||
|
// Consider div scroll position and header element top margin
|
||||||
|
var newSectionOffset = $(this).position().top + previewScrollTop + pxToFloat($(this).css('margin-top'));
|
||||||
|
htmlSectionList.push({
|
||||||
|
startOffset: htmlSectionOffset,
|
||||||
|
endOffset: newSectionOffset,
|
||||||
|
height: newSectionOffset - htmlSectionOffset
|
||||||
|
});
|
||||||
|
htmlSectionOffset = newSectionOffset;
|
||||||
|
});
|
||||||
|
// Last section
|
||||||
|
var scrollHeight = previewElt.prop('scrollHeight');
|
||||||
|
htmlSectionList.push({
|
||||||
|
startOffset: htmlSectionOffset,
|
||||||
|
endOffset: scrollHeight,
|
||||||
|
height: scrollHeight - htmlSectionOffset
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
console.log("mdSectionList: " + _.map(mdSectionList, function(section) {
|
||||||
|
return section.endOffset;
|
||||||
|
}));
|
||||||
|
*/
|
||||||
|
|
||||||
|
// apply Scroll Link
|
||||||
|
lastEditorScrollTop = -99;
|
||||||
|
lastPreviewScrollTop = -99;
|
||||||
|
scrollLink();
|
||||||
|
}, 800);
|
||||||
|
|
||||||
|
var lastEditorScrollTop = -99;
|
||||||
|
var lastPreviewScrollTop = -99;
|
||||||
|
var scrollLink = _.debounce(function() {
|
||||||
|
if(mdSectionList.length === 0 || mdSectionList.length !== htmlSectionList.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var editorElt = $("#wmd-input");
|
||||||
|
var editorScrollTop = editorElt.scrollTop();
|
||||||
|
var previewElt = $("#wmd-preview");
|
||||||
|
var previewScrollTop = previewElt.scrollTop();
|
||||||
|
function animate(srcScrollTop, srcSectionList, destElt, destSectionList) {
|
||||||
|
// Find the section corresponding to the offset
|
||||||
|
var sectionIndex = undefined;
|
||||||
|
var srcSection = _.find(srcSectionList, function(section, index) {
|
||||||
|
sectionIndex = index;
|
||||||
|
return srcScrollTop < section.endOffset;
|
||||||
|
});
|
||||||
|
if(srcSection === undefined) {
|
||||||
|
// Something wrong in the algorithm...
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
var posInSection = (srcScrollTop - srcSection.startOffset) / srcSection.height;
|
||||||
|
var destSection = destSectionList[sectionIndex];
|
||||||
|
var destScrollTop = destSection.startOffset + destSection.height * posInSection;
|
||||||
|
destElt.animate({scrollTop: destScrollTop}, 800, function() {
|
||||||
|
lastEditorScrollTop = editorElt.scrollTop();
|
||||||
|
lastPreviewScrollTop = previewElt.scrollTop();
|
||||||
|
});
|
||||||
|
return destScrollTop;
|
||||||
|
}
|
||||||
|
if(Math.abs(editorScrollTop - lastEditorScrollTop) > 5) {
|
||||||
|
previewScrollTop = animate(editorScrollTop, mdSectionList, previewElt, htmlSectionList);
|
||||||
|
}
|
||||||
|
else if(Math.abs(previewScrollTop - lastPreviewScrollTop) > 5) {
|
||||||
|
editorScrollTop = animate(previewScrollTop, htmlSectionList, editorElt, mdSectionList);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
// Create the layout
|
// Create the layout
|
||||||
core.createLayout = function() {
|
core.createLayout = function() {
|
||||||
var layout = undefined;
|
var layout = undefined;
|
||||||
@ -281,6 +413,9 @@ define(
|
|||||||
togglerLength_closed : 90,
|
togglerLength_closed : 90,
|
||||||
stateManagement__enabled : false
|
stateManagement__enabled : false
|
||||||
};
|
};
|
||||||
|
if(core.settings.scrollLink === true) {
|
||||||
|
layoutGlobalConfig.onresize = buildSections;
|
||||||
|
}
|
||||||
if (core.settings.layoutOrientation == "horizontal") {
|
if (core.settings.layoutOrientation == "horizontal") {
|
||||||
$(".ui-layout-south").remove();
|
$(".ui-layout-south").remove();
|
||||||
$(".ui-layout-east").addClass("well").prop("id", "wmd-preview");
|
$(".ui-layout-east").addClass("well").prop("id", "wmd-preview");
|
||||||
@ -311,8 +446,13 @@ define(
|
|||||||
$("#navbar").click(function() {
|
$("#navbar").click(function() {
|
||||||
layout.allowOverflow('north');
|
layout.allowOverflow('north');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ScrollLink
|
||||||
|
if(core.settings.scrollLink === true) {
|
||||||
|
$("#wmd-input, #wmd-preview").scroll(scrollLink);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the PageDown editor
|
// Create the PageDown editor
|
||||||
var insertLinkCallback = undefined;
|
var insertLinkCallback = undefined;
|
||||||
core.createEditor = function(onTextChange) {
|
core.createEditor = function(onTextChange) {
|
||||||
@ -335,6 +475,11 @@ define(
|
|||||||
return text;
|
return text;
|
||||||
});
|
});
|
||||||
var editor = new Markdown.Editor(converter);
|
var editor = new Markdown.Editor(converter);
|
||||||
|
if(core.settings.scrollLink === true) {
|
||||||
|
editor.hooks.chain("onPreviewRefresh", function() {
|
||||||
|
buildSections();
|
||||||
|
});
|
||||||
|
}
|
||||||
// Custom insert link dialog
|
// Custom insert link dialog
|
||||||
editor.hooks.set("insertLinkDialog", function (callback) {
|
editor.hooks.set("insertLinkDialog", function (callback) {
|
||||||
insertLinkCallback = callback;
|
insertLinkCallback = callback;
|
||||||
@ -709,12 +854,14 @@ define(
|
|||||||
core.createLayout();
|
core.createLayout();
|
||||||
|
|
||||||
// Editor's textarea
|
// Editor's textarea
|
||||||
$("#wmd-input").css({
|
$("#wmd-input, #md-section-helper").css({
|
||||||
// Apply editor font size
|
// Apply editor font size
|
||||||
"font-size": core.settings.editorFontSize + "px",
|
"font-size": core.settings.editorFontSize + "px",
|
||||||
"line-height": Math.round(core.settings.editorFontSize * (20/14)) + "px"
|
"line-height": Math.round(core.settings.editorFontSize * (20/14)) + "px"
|
||||||
}).keydown(function(e) {
|
});
|
||||||
// Manage tab key
|
|
||||||
|
// Manage tab key
|
||||||
|
$("#wmd-input").keydown(function(e) {
|
||||||
if(e.keyCode === 9) {
|
if(e.keyCode === 9) {
|
||||||
var value = $(this).val();
|
var value = $(this).val();
|
||||||
var start = this.selectionStart;
|
var start = this.selectionStart;
|
||||||
@ -729,6 +876,45 @@ define(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Tooltips
|
||||||
|
$(".tooltip-scroll-link").tooltip({
|
||||||
|
html: true,
|
||||||
|
container: '#modal-settings',
|
||||||
|
placement: 'right',
|
||||||
|
title: ['Scroll Link is a feature that binds together editor and preview scrollbars. ',
|
||||||
|
'It allows you to keep an eye on the preview while scrolling the editor and vice versa. ',
|
||||||
|
'<br><br>',
|
||||||
|
'The mapping between Markdown and HTML is based on the position of the title elements (h1, h2, ...) in the page. ',
|
||||||
|
'Therefore, if your document does not contain any title, the mapping will be linear and consequently less efficient.',
|
||||||
|
].join("")
|
||||||
|
});
|
||||||
|
$(".tooltip-template").tooltip({
|
||||||
|
html: true,
|
||||||
|
container: '#modal-settings',
|
||||||
|
placement: 'right',
|
||||||
|
trigger: 'manual',
|
||||||
|
title: ['Available variables:<br>',
|
||||||
|
'<ul><li><b>documentTitle</b>: document title</li>',
|
||||||
|
'<li><b>documentMarkdown</b>: document in Markdown format</li>',
|
||||||
|
'<li><b>documentHTML</b>: document in HTML format</li>',
|
||||||
|
'<li><b>publishAttributes</b>: attributes of the publish location (undefined when using "Save")</li></ul>',
|
||||||
|
'Examples:<br>',
|
||||||
|
_.escape('<title><%= documentTitle %></title>'),
|
||||||
|
'<br>',
|
||||||
|
_.escape('<div><%- documentHTML %></div>'),
|
||||||
|
'<br>',
|
||||||
|
_.escape('<% if(publishAttributes.provider == "github") print(documentMarkdown); %>'),
|
||||||
|
'<br><br><a target="_blank" href="http://underscorejs.org/#template">More info</a>',
|
||||||
|
].join("")
|
||||||
|
}).click(function(e) {
|
||||||
|
$(this).tooltip('show');
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).click(function(e) {
|
||||||
|
$(".tooltip-template").tooltip('hide');
|
||||||
|
});
|
||||||
|
|
||||||
// Reset inputs
|
// Reset inputs
|
||||||
$(".action-reset-input").click(function() {
|
$(".action-reset-input").click(function() {
|
||||||
core.resetModalInputs();
|
core.resetModalInputs();
|
||||||
|
156
js/css_browser_selector.js
Normal file
156
js/css_browser_selector.js
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
CSS Browser Selector 0.6.1
|
||||||
|
Originally written by Rafael Lima (http://rafael.adm.br)
|
||||||
|
http://rafael.adm.br/css_browser_selector
|
||||||
|
License: http://creativecommons.org/licenses/by/2.5/
|
||||||
|
|
||||||
|
Co-maintained by:
|
||||||
|
https://github.com/verbatim/css_browser_selector
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
showLog=true;
|
||||||
|
function log(m) {if ( window.console && showLog ) {console.log(m); } }
|
||||||
|
|
||||||
|
function css_browser_selector(u)
|
||||||
|
{
|
||||||
|
var uaInfo = {},
|
||||||
|
screens = [320, 480, 640, 768, 1024, 1152, 1280, 1440, 1680, 1920, 2560],
|
||||||
|
allScreens = screens.length,
|
||||||
|
ua=u.toLowerCase(),
|
||||||
|
is=function(t) { return RegExp(t,"i").test(ua); },
|
||||||
|
version = function(p,n)
|
||||||
|
{
|
||||||
|
n=n.replace(".","_"); var i = n.indexOf('_'), ver="";
|
||||||
|
while (i>0) {ver += " "+ p+n.substring(0,i);i = n.indexOf('_', i+1);}
|
||||||
|
ver += " "+p+n; return ver;
|
||||||
|
},
|
||||||
|
g='gecko',
|
||||||
|
w='webkit',
|
||||||
|
c='chrome',
|
||||||
|
f='firefox',
|
||||||
|
s='safari',
|
||||||
|
o='opera',
|
||||||
|
m='mobile',
|
||||||
|
a='android',
|
||||||
|
bb='blackberry',
|
||||||
|
lang='lang_',
|
||||||
|
dv='device_',
|
||||||
|
html=document.documentElement,
|
||||||
|
b= [
|
||||||
|
|
||||||
|
// browser
|
||||||
|
(!(/opera|webtv/i.test(ua))&&/msie\s(\d+)/.test(ua))?('ie ie'+(/trident\/4\.0/.test(ua) ? '8' : RegExp.$1))
|
||||||
|
:is('firefox/')?g+ " " + f+(/firefox\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua)?' '+f+RegExp.$2 + ' '+f+RegExp.$2+"_"+RegExp.$4:'')
|
||||||
|
:is('gecko/')?g
|
||||||
|
:is('opera')?o+(/version\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua)?' '+o+RegExp.$2 + ' '+o+RegExp.$2+"_"+RegExp.$4 : (/opera(\s|\/)(\d+)\.(\d+)/.test(ua)?' '+o+RegExp.$2+" "+o+RegExp.$2+"_"+RegExp.$3:''))
|
||||||
|
:is('konqueror')?'konqueror'
|
||||||
|
|
||||||
|
:is('blackberry') ?
|
||||||
|
( bb +
|
||||||
|
( /Version\/(\d+)(\.(\d+)+)/i.test(ua)
|
||||||
|
? " " + bb+ RegExp.$1 + " "+bb+ RegExp.$1+RegExp.$2.replace('.','_')
|
||||||
|
: (/Blackberry ?(([0-9]+)([a-z]?))[\/|;]/gi.test(ua)
|
||||||
|
? ' ' +bb+RegExp.$2 + (RegExp.$3?' ' +bb+RegExp.$2+RegExp.$3:'')
|
||||||
|
: '')
|
||||||
|
)
|
||||||
|
) // blackberry
|
||||||
|
|
||||||
|
:is('android') ?
|
||||||
|
( a +
|
||||||
|
( /Version\/(\d+)(\.(\d+))+/i.test(ua)
|
||||||
|
? " " + a+ RegExp.$1 + " "+a+ RegExp.$1+RegExp.$2.replace('.','_')
|
||||||
|
: '')
|
||||||
|
+ (/Android (.+); (.+) Build/i.test(ua)
|
||||||
|
? ' '+dv+( (RegExp.$2).replace(/ /g,"_") ).replace(/-/g,"_")
|
||||||
|
:'' )
|
||||||
|
) //android
|
||||||
|
|
||||||
|
:is('chrome')?w+ ' '+c+(/chrome\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua)?' '+c+RegExp.$2 +((RegExp.$4>0) ? ' '+c+RegExp.$2+"_"+RegExp.$4:''):'')
|
||||||
|
|
||||||
|
:is('iron')?w+' iron'
|
||||||
|
|
||||||
|
:is('applewebkit/') ?
|
||||||
|
( w+ ' '+ s +
|
||||||
|
( /version\/((\d+)(\.(\d+))(\.\d+)*)/.test(ua)
|
||||||
|
? ' '+ s +RegExp.$2 + " "+s+ RegExp.$2+RegExp.$3.replace('.','_')
|
||||||
|
: ( / Safari\/(\d+)/i.test(ua)
|
||||||
|
?
|
||||||
|
( (RegExp.$1=="419" || RegExp.$1=="417" || RegExp.$1=="416" || RegExp.$1=="412" ) ? ' '+ s + '2_0'
|
||||||
|
: RegExp.$1=="312" ? ' '+ s + '1_3'
|
||||||
|
: RegExp.$1=="125" ? ' '+ s + '1_2'
|
||||||
|
: RegExp.$1=="85" ? ' '+ s + '1_0'
|
||||||
|
: '' )
|
||||||
|
:'')
|
||||||
|
)
|
||||||
|
) //applewebkit
|
||||||
|
|
||||||
|
:is('mozilla/')?g
|
||||||
|
:''
|
||||||
|
|
||||||
|
// mobile
|
||||||
|
,is("android|mobi|mobile|j2me|iphone|ipod|ipad|blackberry|playbook|kindle|silk")?m:''
|
||||||
|
|
||||||
|
// os/platform
|
||||||
|
,is('j2me')?'j2me'
|
||||||
|
:is('ipad|ipod|iphone')?
|
||||||
|
(
|
||||||
|
(
|
||||||
|
/CPU( iPhone)? OS (\d+[_|\.]\d+([_|\.]\d+)*)/i.test(ua) ?
|
||||||
|
'ios' + version('ios',RegExp.$2) : ''
|
||||||
|
) + ' ' + ( /(ip(ad|od|hone))/gi.test(ua) ? RegExp.$1 : "" )
|
||||||
|
) //'iphone'
|
||||||
|
//:is('ipod')?'ipod'
|
||||||
|
//:is('ipad')?'ipad'
|
||||||
|
:is('playbook')?'playbook'
|
||||||
|
:is('kindle|silk')?'kindle'
|
||||||
|
:is('playbook')?'playbook'
|
||||||
|
:is('mac')?'mac'+ (/mac os x ((\d+)[.|_](\d+))/.test(ua) ? ( ' mac' + (RegExp.$2) + ' mac' + (RegExp.$1).replace('.',"_") ) : '' )
|
||||||
|
:is('win')?'win'+
|
||||||
|
(is('windows nt 6.2')?' win8'
|
||||||
|
:is('windows nt 6.1')?' win7'
|
||||||
|
:is('windows nt 6.0')?' vista'
|
||||||
|
:is('windows nt 5.2') || is('windows nt 5.1') ? ' win_xp'
|
||||||
|
:is('windows nt 5.0')?' win_2k'
|
||||||
|
:is('windows nt 4.0') || is('WinNT4.0') ?' win_nt'
|
||||||
|
: ''
|
||||||
|
)
|
||||||
|
:is('freebsd')?'freebsd'
|
||||||
|
:(is('x11|linux'))?'linux'
|
||||||
|
:''
|
||||||
|
|
||||||
|
// user agent language
|
||||||
|
,(/[; |\[](([a-z]{2})(\-[a-z]{2})?)[)|;|\]]/i.test(ua))?(lang+RegExp.$2).replace("-","_")+(RegExp.$3!=''?(' '+lang+RegExp.$1).replace("-","_"):''):''
|
||||||
|
|
||||||
|
// beta: test if running iPad app
|
||||||
|
,( is('ipad|iphone|ipod') && !is('safari') ) ? 'ipad_app' : ''
|
||||||
|
|
||||||
|
|
||||||
|
]; // b
|
||||||
|
|
||||||
|
function screenSize()
|
||||||
|
{
|
||||||
|
var w = window.outerWidth || html.clientWidth;
|
||||||
|
var h = window.outerHeight || html.clientHeight;
|
||||||
|
uaInfo.orientation = ((w<h) ? "portrait" : "landscape");
|
||||||
|
// remove previous min-width, max-width, client-width, client-height, and orientation
|
||||||
|
html.className = html.className.replace(/ ?orientation_\w+/g, "").replace(/ [min|max|cl]+[w|h]_\d+/g, "")
|
||||||
|
for (var i=(allScreens-1);i>=0;i--) { if (w >= screens[i] ) { uaInfo.maxw = screens[i]; break; }}
|
||||||
|
widthClasses="";
|
||||||
|
for (var info in uaInfo) { widthClasses+=" "+info+"_"+ uaInfo[info] };
|
||||||
|
html.className = ( html.className +widthClasses );
|
||||||
|
return widthClasses;
|
||||||
|
} // screenSize
|
||||||
|
|
||||||
|
window.onresize = screenSize;
|
||||||
|
screenSize();
|
||||||
|
|
||||||
|
var cssbs = (b.join(' ')) + " js ";
|
||||||
|
html.className = ( cssbs + html.className.replace(/\b(no[-|_]?)?js\b/g,"") ).replace(/^ /, "").replace(/ +/g," ");
|
||||||
|
|
||||||
|
return cssbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
css_browser_selector(navigator.userAgent);
|
||||||
|
|
||||||
|
|
13
js/main-min.js
vendored
13
js/main-min.js
vendored
File diff suppressed because one or more lines are too long
@ -221,33 +221,6 @@ define(["jquery", "core", "github-provider", "blogger-provider", "dropbox-provid
|
|||||||
publisher.publish();
|
publisher.publish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".tooltip-template").tooltip({
|
|
||||||
html: true,
|
|
||||||
container: '#modal-settings',
|
|
||||||
placement: 'right',
|
|
||||||
trigger: 'manual',
|
|
||||||
title: ['Available variables:<br>',
|
|
||||||
'<ul><li><b>documentTitle</b>: document title</li>',
|
|
||||||
'<li><b>documentMarkdown</b>: document in Markdown format</li>',
|
|
||||||
'<li><b>documentHTML</b>: document in HTML format</li>',
|
|
||||||
'<li><b>publishAttributes</b>: attributes of the publish location (undefined when using "Save")</li></ul>',
|
|
||||||
'Examples:<br>',
|
|
||||||
_.escape('<title><%= documentTitle %></title>'),
|
|
||||||
'<br>',
|
|
||||||
_.escape('<div><%- documentHTML %></div>'),
|
|
||||||
'<br>',
|
|
||||||
_.escape('<% if(publishAttributes.provider == "github") print(documentMarkdown); %>'),
|
|
||||||
'<br><br><a target="_blank" href="http://underscorejs.org/#template">More info</a>',
|
|
||||||
].join("")
|
|
||||||
}).click(function(e) {
|
|
||||||
$(this).tooltip('show');
|
|
||||||
e.stopPropagation();
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).click(function(e) {
|
|
||||||
$(".tooltip-template").tooltip('hide');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return publisher;
|
return publisher;
|
||||||
|
Loading…
Reference in New Issue
Block a user