From 4b0ca55eb79e963523eb6c8197825e9e8ae904e2 Mon Sep 17 00:00:00 2001 From: Wu Cheng-Han Date: Mon, 4 May 2015 15:53:29 +0800 Subject: First commit, version 0.2.7 --- public/js/cover.js | 311 +++++++++++++++++ public/js/extra.js | 278 +++++++++++++++ public/js/ga.js | 14 + public/js/history.js | 256 ++++++++++++++ public/js/index.js | 940 +++++++++++++++++++++++++++++++++++++++++++++++++++ public/js/unused.js | 45 +++ 6 files changed, 1844 insertions(+) create mode 100644 public/js/cover.js create mode 100644 public/js/extra.js create mode 100644 public/js/ga.js create mode 100644 public/js/history.js create mode 100644 public/js/index.js create mode 100644 public/js/unused.js (limited to 'public/js') diff --git a/public/js/cover.js b/public/js/cover.js new file mode 100644 index 00000000..fea51f6a --- /dev/null +++ b/public/js/cover.js @@ -0,0 +1,311 @@ +$(".masthead-nav li").click(function () { + $(this).siblings().removeClass("active"); + $(this).addClass("active"); +}); + +$(".ui-home").click(function () { + $(".section").hide(); + $("#home").fadeIn(); +}); + +$(".ui-history").click(function () { + $(".section").hide(); + $("#history").fadeIn(); +}); + +$(".ui-releasenotes").click(function () { + $(".section").hide(); + $("#releasenotes").fadeIn(); +}); + +function checkHistoryList() { + if ($("#history-list").children().length > 0) + $(".ui-nohistory").hide(); + else if ($("#history-list").children().length == 0) { + $(".ui-nohistory").slideDown(); + var cookienotehistory = JSON.parse($.cookie('notehistory')); + if (login && cookienotehistory && cookienotehistory.length > 0) { + $(".ui-import-from-cookie").slideDown(); + } + } +} + +function parseHistoryCallback() { + checkHistoryList(); + $(".ui-history-close").click(function (e) { + e.preventDefault(); + var id = $(this).closest("a").attr("href").split('/')[1]; + getHistory(function (notehistory) { + var newnotehistory = removeHistory(id, notehistory); + saveHistory(newnotehistory); + }); + $(this).closest("li").remove(); + checkHistoryList(); + }); +} + +var login = false; + +checkIfAuth( + function (data) { + $('.ui-signin').hide(); + $('.ui-or').hide(); + $('.ui-welcome').show(); + $('.ui-name').html(data.name); + $('.ui-signout').show(); + $(".ui-history").click(); + login = true; + }, + function () { + $('.ui-signin').slideDown(); + $('.ui-or').slideDown(); + login = false; + } +); + +parseHistory(parseHistoryCallback); + +$(".ui-import-from-cookie").click(function () { + saveCookieHistoryToServer(function() { + parseCookieToHistory(parseHistoryCallback); + $(".ui-import-from-cookie").hide(); + }); +}); + +var source = $("#template").html(); +var template = Handlebars.compile(source); +var context = { + release: [ + { + version: "0.2.7", + tag: "fuel", + date: moment("201505031200", 'YYYYMMDDhhmm').fromNow(), + detail: [ + { + title: "Features", + item: [ + "+ Support facebook, twitter, github, dropbox login", + "+ Support own history" + ] + }, + { + title: "Enhancements", + item: [ + "* Adjust history ui", + "* Upgrade realtime package", + "* Upgrade editor package, now support composition input better" + ] + }, + { + title: "Fixes", + item: [ + "* Partial update might not render properly", + "* Cursor focus might not at correct position" + ] + } + ] + }, + { + version: "0.2.6", + tag: "zippo", + date: moment("201504241600", 'YYYYMMDDhhmm').fromNow(), + detail: [ + { + title: "Features", + item: [ + "+ Support sync scroll", + "+ Support partial update" + ] + }, + { + title: "Enhancements", + item: [ + "* Added feedback ui", + "* Adjust animations and delays", + "* Adjust editor viewportMargin for performance", + "* Adjust emit refresh event occasion", + "* Added editor fallback fonts", + "* Index page auto focus at history if valid" + ] + }, + { + title: "Fixes", + item: [ + "* Server might not disconnect client properly", + "* Resume connection might restore wrong info" + ] + } + ] + }, + { + version: "0.2.5", + tag: "lightning", + date: moment("201504142110", 'YYYYMMDDhhmm').fromNow(), + detail: [ + { + title: "Features", + item: [ + "+ Support import from dropbox and clipboard", + "+ Support more code highlighting", + "+ Support mathjax, sequence diagram and flow chart" + ] + }, + { + title: "Enhancements", + item: [ + "* Adjust toolbar and layout style", + "* Adjust mobile layout style", + "* Adjust history layout style", + "* Server using heartbeat to gain accuracy of online users" + ] + }, + { + title: "Fixes", + item: [ + "* Virtual keyboard might broken the navbar", + "* Adjust editor viewportMargin for preloading content" + ] + } + ] + }, + { + version: "0.2.4", + tag: "flint", + date: moment("201504101240", 'YYYYMMDDhhmm').fromNow(), + detail: [ + { + title: "Features", + item: [ + "+ Support save to dropbox", + "+ Show other users' cursor with light color" + ] + }, + { + title: "Enhancements", + item: [ + "* Adjust toolbar layout style for future" + ] + }, + { + title: "Fixes", + item: [ + "* Title might not render properly", + "* Code border style might not show properly", + "* Server might not connect concurrent client properly" + ] + } + ] + }, + { + version: "0.2.3", + tag: "light", + date: moment("201504062030", 'YYYYMMDDhhmm').fromNow(), + detail: [ + { + title: "Features", + item: [ + "+ Support youtube, vimeo", + "+ Support gist", + "+ Added quick link in pretty", + "+ Added font-smoothing style" + ] + }, + { + title: "Enhancements", + item: [ + "* Change the rendering engine to remarkable", + "* Adjust view, todo list layout style for UX", + "+ Added responsive layout check", + "+ Auto reload if client version mismatch", + "+ Keep history stack after reconnect if nothing changed", + "+ Added features page" + ] + }, + { + title: "Fixes", + item: [ + "* Closetags auto input might not have proper origin", + "* Autofocus on editor only if it's on desktop", + "+ Prevent using real script and iframe tags", + "* Sorting in history by time not percise" + ] + } + ] + }, + { + version: "0.2.2", + tag: "fire", + date: moment("201503272110", 'YYYYMMDDhhmm').fromNow(), + detail: [ + { + title: "Features", + item: [ + "+ Support smartLists, smartypants", + "+ Support line number on code block", + "+ Support tags and search or sort history" + ] + }, + { + title: "Enhancements", + item: [ + "+ Added delay on socket change", + "+ Updated markdown-body width to match github style", + "+ Socket changes now won't add to editor's history", + "* Reduce redundant server events" + ] + }, + { + title: "Fixes", + item: [ + "* Toolbar links might get wrong", + "* Wrong action redirections" + ] + } + ] + }, + { + version: "0.2.1", + tag: "spark", + date: moment("201503171340", 'YYYYMMDDhhmm').fromNow(), + detail: [ + { + title: "Features", + item: [ + "+ Support github-like todo-list", + "+ Support emoji" + ] + }, + { + title: "Enhancements", + item: [ + "+ Added more effects on transition", + "+ Reduced rendering delay", + "+ Auto close and match brackets", + "+ Auto close and match tags", + "+ Added code fold and fold gutters", + "+ Added continue listing of markdown" + ] + } + ] + }, + { + version: "0.2.0", + tag: "launch-day", + date: moment("201503142020", 'YYYYMMDDhhmm').fromNow(), + detail: [ + { + title: "Features", + item: [ + "+ Markdown editor", + "+ Preview html", + "+ Realtime collaborate", + "+ Cross-platformed", + "+ Recently used history" + ] + } + ] + } + ] +}; +var html = template(context); +$("#releasenotes").html(html); \ No newline at end of file diff --git a/public/js/extra.js b/public/js/extra.js new file mode 100644 index 00000000..45833c89 --- /dev/null +++ b/public/js/extra.js @@ -0,0 +1,278 @@ +//get title +function getTitle(view) { + var h1s = view.find("h1"); + var title = ""; + if (h1s.length > 0) { + title = h1s.first().text(); + } else { + title = null; + } + return title; +} +//render title +function renderTitle(view) { + var title = getTitle(view); + if (title) { + title += ' - HackMD'; + } else { + title = 'HackMD - Collaborative notes'; + } + return title; +} +//render filename +function renderFilename(view) { + var filename = getTitle(view); + if (!filename) { + filename = 'Untitled'; + } + return filename; +} + +//dynamic event or object binding here +function finishView(view) { + //youtube + view.find(".youtube").click(function () { + imgPlayiframe(this, '//www.youtube.com/embed/'); + }); + //vimeo + view.find(".vimeo") + .click(function () { + imgPlayiframe(this, '//player.vimeo.com/video/'); + }) + .each(function (key, value) { + $.ajax({ + type: 'GET', + url: 'http://vimeo.com/api/v2/video/' + $(value).attr('videoid') + '.json', + jsonp: 'callback', + dataType: 'jsonp', + success: function (data) { + var thumbnail_src = data[0].thumbnail_large; + $(value).css('background-image', 'url(' + thumbnail_src + ')'); + } + }); + }); + //gist + view.find("code[data-gist-id]").each(function(key, value) { + if($(value).children().length == 0) + $(value).gist(); + }); + //emojify + emojify.run(view[0]); + //mathjax + var mathjaxdivs = view.find('.mathjax').toArray(); + try { + for (var i = 0; i < mathjaxdivs.length; i++) { + MathJax.Hub.Queue(["Typeset", MathJax.Hub, mathjaxdivs[i].innerHTML]); + $(mathjaxdivs[i]).removeClass("mathjax"); + } + } catch(err) { + } + //sequence diagram + var sequence = view.find(".sequence-diagram"); + try { + sequence.sequenceDiagram({ + theme: 'simple' + }); + sequence.parent().parent().replaceWith(sequence); + sequence.removeClass("sequence-diagram"); + } catch(err) { + console.error(err); + } + //flowchart + var flow = view.find(".flow-chart"); + flow.each(function (key, value) { + try { + var chart = flowchart.parse($(value).text()); + $(value).html(''); + chart.drawSVG(value, { + 'line-width': 2, + 'fill': 'none', + 'font-size': '16px', + 'font-family': "'Andale Mono', monospace" + }); + $(value).parent().parent().replaceWith(value); + $(value).removeClass("flow-chart"); + } catch(err) { + console.error(err); + } + }); + //render title + document.title = renderTitle(view); +} +//only static transform should be here +function postProcess(code) { + var result = $('
' + code + '
'); + //prevent XSS + result.find("script").replaceWith(function () { + return "" + }); + result.find("iframe").replaceWith(function () { + return "" + $(this).html() + "" + }); + //todo list + var lis = result[0].getElementsByTagName('li'); + for (var i = 0; i < lis.length; i++) { + var html = lis[i].innerHTML; + if (/^\s*\[[x ]\]\s+/.test(html)) { + lis[i].innerHTML = html.replace(/^\s*\[ \]\s*/, '') + .replace(/^\s*\[x\]\s*/, ''); + lis[i].setAttribute('class', 'task-list-item'); + } + } + return result; +} + +function setSizebyAttr(element, target) { + var width = $(element).attr("width") ? $(element).attr("width") : '100%'; + var height = $(element).attr("height") ? $(element).attr("height") : '360px'; + $(target).width(width); + $(target).height(height); +} + +function imgPlayiframe(element, src) { + if (!$(element).attr("videoid")) return; + var iframe = $(""); + $(iframe).attr("src", src + $(element).attr("videoid") + '?autoplay=1'); + setSizebyAttr(element, iframe); + $(element).html(iframe); +} + +var anchorForId = function (id) { + var anchor = document.createElement("a"); + anchor.className = "header-link"; + anchor.href = "#" + id; + anchor.innerHTML = "Permalink"; + anchor.title = "Permalink"; + return anchor; +}; + +var linkifyAnchors = function (level, containingElement) { + var headers = containingElement.getElementsByTagName("h" + level); + for (var h = 0; h < headers.length; h++) { + var header = headers[h]; + + if (typeof header.id == "undefined" || header.id == "") { + var id = S(header.innerHTML.toLowerCase()).trim().stripTags().dasherize().s; + header.id = encodeURIComponent(id); + } + header.appendChild(anchorForId(header.id)); + } +}; + +function autoLinkify(view) { + var contentBlock = view[0]; + if (!contentBlock) { + return; + } + for (var level = 1; level <= 6; level++) { + linkifyAnchors(level, contentBlock); + } +}; + +function scrollToHash() { + var hash = location.hash; + location.hash = ""; + location.hash = hash; +} + +function highlightRender(code, lang) { + if (!lang || /no(-?)highlight|plain|text/.test(lang)) + return; + if(lang == 'sequence') { + return '
' + code + '
'; + } else if(lang == 'flow') { + return '
' + code + '
'; + } + var reallang = lang.replace('=', ''); + var languages = hljs.listLanguages(); + if (languages.indexOf(reallang) == -1) { + var result = hljs.highlightAuto(code); + } else { + var result = hljs.highlight(reallang, code); + } + if (/\=$/.test(lang)) { + var lines = result.value.split('\n'); + var linenumbers = []; + for (var i = 0; i < lines.length; i++) { + linenumbers[i] = "
" + (i + 1) + "
"; + } + var linegutter = "
" + linenumbers.join('\n') + "
"; + result.value = "
" + linegutter + "
" + result.value + "
"; + } + return result.value; +} + +emojify.setConfig({ + img_dir: '/vendor/emojify/images', + ignore_emoticons: true +}); + +var md = new Remarkable('full', { + html: true, + linkify: true, + typographer: true, + highlight: highlightRender +}); +//youtube +var youtubePlugin = new Plugin( + // regexp to match + /{%youtube\s*([\d\D]*?)\s*%}/, + + // this function will be called when something matches + function (match, utils) { + var videoid = match[1]; + if (!videoid) return; + var div = $('
'); + setSizebyAttr(div, div); + div.attr('videoid', videoid); + var icon = ''; + div.append(icon); + var thumbnail_src = '//img.youtube.com/vi/' + videoid + '/hqdefault.jpg'; + div.css('background-image', 'url(' + thumbnail_src + ')'); + return div[0].outerHTML; + } +); +//vimeo +var vimeoPlugin = new Plugin( + // regexp to match + /{%vimeo\s*([\d\D]*?)\s*%}/, + + // this function will be called when something matches + function (match, utils) { + var videoid = match[1]; + if (!videoid) return; + var div = $('
'); + setSizebyAttr(div, div); + div.attr('videoid', videoid); + var icon = ''; + div.append(icon); + return div[0].outerHTML; + } +); +//gist +var gistPlugin = new Plugin( + // regexp to match + /{%gist\s*([\d\D]*?)\s*%}/, + + // this function will be called when something matches + function (match, utils) { + var gistid = match[1]; + var code = ''; + return code; + } +); +//mathjax +var mathjaxPlugin = new Plugin( + // regexp to match + /^\$\$\n([\d\D]*?)\n\$\$$|\$([\d\D]*?)\$/, + + // this function will be called when something matches + function (match, utils) { + //var code = $(match).text(); + return '' + match[0] + ''; + } +); +md.use(youtubePlugin); +md.use(vimeoPlugin); +md.use(gistPlugin); +md.use(mathjaxPlugin); \ No newline at end of file diff --git a/public/js/ga.js b/public/js/ga.js new file mode 100644 index 00000000..0fda2410 --- /dev/null +++ b/public/js/ga.js @@ -0,0 +1,14 @@ +(function (i, s, o, g, r, a, m) { + i['GoogleAnalyticsObject'] = r; + i[r] = i[r] || function () { + (i[r].q = i[r].q || []).push(arguments) + }, i[r].l = 1 * new Date(); + a = s.createElement(o), + m = s.getElementsByTagName(o)[0]; + a.async = 1; + a.src = g; + m.parentNode.insertBefore(a, m) +})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga'); + +ga('create', 'get your self one', 'auto'); +ga('send', 'pageview'); \ No newline at end of file diff --git a/public/js/history.js b/public/js/history.js new file mode 100644 index 00000000..c6deaa53 --- /dev/null +++ b/public/js/history.js @@ -0,0 +1,256 @@ +//common +function checkIfAuth(yesCallback, noCallback) { + $.get('/me') + .done(function (data) { + if (data && data.status == 'ok') { + yesCallback(data); + } else { + noCallback(); + } + }) + .fail(function () { + noCallback(); + }); +} + +function saveHistory(notehistory) { + checkIfAuth( + function () { + saveHistoryToServer(notehistory); + }, + function () { + saveHistoryToCookie(notehistory); + } + ); +} + +function saveHistoryToCookie(notehistory) { + $.cookie('notehistory', JSON.stringify(notehistory), { + expires: 365 + }); +} + +function saveHistoryToServer(notehistory) { + $.post('/history', { + history: JSON.stringify(notehistory) + }); +} + +function saveCookieHistoryToServer(callback) { + $.post('/history', { + history: $.cookie('notehistory') + }) + .done(function (data) { + callback(); + }); +} + +function clearDuplicatedHistory(notehistory) { + var newnotehistory = []; + for (var i = 0; i < notehistory.length; i++) { + var found = false; + for (var j = 0; j < newnotehistory.length; j++) { + if (notehistory[i].id == newnotehistory[j].id) { + found = true; + break; + } + } + if (!found) + newnotehistory.push(notehistory[i]); + } + return notehistory; +} + +function addHistory(id, text, time, tags, notehistory) { + notehistory.push({ + id: id, + text: text, + time: time, + tags: tags + }); + return notehistory; +} + +function removeHistory(id, notehistory) { + for (var i = 0; i < notehistory.length; i++) { + if (notehistory[i].id == id) + notehistory.splice(i, 1); + } + return notehistory; +} + +//used for inner +function writeHistory(view) { + checkIfAuth( + function () { + writeHistoryToServer(view); + }, + function () { + writeHistoryToCookie(view); + } + ); +} + +function writeHistoryToServer(view) { + $.get('/history') + .done(function (data) { + try { + if (data.history) { + var notehistory = data.history; + } else { + var notehistory = []; + } + } catch (err) { + var notehistory = []; + } + var newnotehistory = generateHistory(view, notehistory); + saveHistoryToServer(newnotehistory); + }) + .fail(function () { + writeHistoryToCookie(view); + }); +} + +function writeHistoryToCookie(view) { + try { + var notehistory = JSON.parse($.cookie('notehistory')); + } catch (err) { + var notehistory = []; + } + + var newnotehistory = generateHistory(view, notehistory); + saveHistoryToCookie(newnotehistory); +} + +function renderHistory(view) { + var title = renderFilename(view); + + var tags = []; + var rawtags = []; + view.find('h6').each(function (key, value) { + if (/^tags/gmi.test($(value).text())) { + var codes = $(value).find("code"); + for (var i = 0; i < codes.length; i++) + rawtags.push(codes[i]); + } + }); + for (var i = 0; i < rawtags.length; i++) { + var found = false; + for (var j = 0; j < tags.length; j++) { + if (tags[j] == rawtags[i].innerHTML) { + found = true; + break; + } + } + if (!found) + tags.push(rawtags[i].innerHTML); + } + //console.debug(tags); + return { + id: location.pathname.split('/')[1], + text: title, + time: moment().format('MMMM Do YYYY, h:mm:ss a'), + tags: tags + }; +} + +function generateHistory(view, notehistory) { + var info = renderHistory(view); + notehistory = clearDuplicatedHistory(notehistory); + notehistory = removeHistory(info.id, notehistory); + notehistory = addHistory(info.id, info.text, info.time, info.tags, notehistory); + return notehistory; +} + +//used for outer +function getHistory(callback) { + checkIfAuth( + function () { + getServerHistory(callback); + }, + function () { + getCookieHistory(callback); + } + ); +} + +function getServerHistory(callback) { + $.get('/history') + .done(function (data) { + if (data.history) { + callback(data.history); + } + }) + .fail(function () { + getCookieHistory(callback); + }); +} + +function getCookieHistory(callback) { + callback(JSON.parse($.cookie('notehistory'))); +} + +function parseHistory(callback) { + checkIfAuth( + function () { + parseServerToHistory(callback); + }, + function () { + parseCookieToHistory(callback); + } + ); +} + +function parseServerToHistory(callback) { + $.get('/history') + .done(function (data) { + if (data.history) { + //console.log(data.history); + parseToHistory(data.history, callback); + } + }) + .fail(function () { + parseCookieToHistory(callback); + }); +} + +function parseCookieToHistory(callback) { + var notehistory = JSON.parse($.cookie('notehistory')); + parseToHistory(notehistory, callback); +} + +function parseToHistory(notehistory, callback) { + if (notehistory && notehistory.length > 0) { + //console.log(notehistory); + for (var i = 0; i < notehistory.length; i++) { + notehistory[i].timestamp = moment(notehistory[i].time, 'MMMM Do YYYY, h:mm:ss a').unix(); + notehistory[i].fromNow = moment(notehistory[i].time, 'MMMM Do YYYY, h:mm:ss a').fromNow(); + } + $(notehistory).each(function (key, value) { + var close = "
"; + var text = "

" + value.text + "

"; + var timestamp = ""; + var fromNow = " " + value.fromNow + ""; + var time = "" + value.time + ""; + var tags = ""; + if (value.tags) { + var labels = []; + for (var j = 0; j < value.tags.length; j++) + labels.push("" + value.tags[j] + ""); + tags = "

" + labels.join(" ") + "

"; + } + var li = "
  • " + close + text + '

    ' + fromNow + '
    ' + timestamp + time + '

    ' + tags + "
  • " + //console.debug(li); + $("#history-list").append(li); + }); + } + + var options = { + valueNames: ['text', 'timestamp', 'fromNow', 'time', 'tags'] + }; + var historyList = new List('history', options); + historyList.sort('timestamp', { + order: "desc" + }); + callback(); +} \ No newline at end of file diff --git a/public/js/index.js b/public/js/index.js new file mode 100644 index 00000000..73b4e594 --- /dev/null +++ b/public/js/index.js @@ -0,0 +1,940 @@ +//constant vars +//settings +var debug = false; +var version = '0.2.7'; +var doneTypingDelay = 400; +var finishChangeDelay = 400; +var cursorActivityDelay = 50; +var syncScrollDelay = 50; +var scrollAnimatePeriod = 100; +var cursorAnimatePeriod = 100; +var modeType = { + edit: {}, + view: {}, + both: {} +} +var statusType = { + connected: { + msg: "CONNECTED", + label: "label-warning", + fa: "fa-wifi" + }, + online: { + msg: "ONLINE: ", + label: "label-primary", + fa: "fa-users" + }, + offline: { + msg: "OFFLINE", + label: "label-danger", + fa: "fa-plug" + } +} +var defaultMode = modeType.both; + +//global vars +var loaded = false; +var isDirty = false; +var editShown = false; +var visibleXS = false; +var visibleSM = false; +var visibleMD = false; +var visibleLG = false; +var isTouchDevice = 'ontouchstart' in document.documentElement; +var currentMode = defaultMode; +var currentStatus = statusType.offline; +var lastInfo = { + needRestore: false, + cursor: null, + scroll: null, + edit: { + scroll: { + left: null, + top: null + }, + cursor: { + line: null, + ch: null + } + }, + view: { + scroll: { + left: null, + top: null + } + }, + history: null +}; + +//editor settings +var editor = CodeMirror.fromTextArea(document.getElementById("textit"), { + mode: 'gfm', + viewportMargin: 20, + styleActiveLine: true, + lineNumbers: true, + lineWrapping: true, + theme: "monokai", + autofocus: true, + inputStyle: "textarea", + matchBrackets: true, + autoCloseBrackets: true, + matchTags: { + bothTags: true + }, + autoCloseTags: true, + foldGutter: true, + gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"], + extraKeys: { + "Enter": "newlineAndIndentContinueMarkdownList" + }, + readOnly: true +}); + +//ui vars +var ui = { + spinner: $(".ui-spinner"), + content: $(".ui-content"), + toolbar: { + shortStatus: $(".ui-short-status"), + status: $(".ui-status"), + new: $(".ui-new"), + pretty: $(".ui-pretty"), + download: { + markdown: $(".ui-download-markdown") + }, + save: { + dropbox: $(".ui-save-dropbox") + }, + import: { + dropbox: $(".ui-import-dropbox"), + clipboard: $(".ui-import-clipboard") + }, + mode: $(".ui-mode"), + edit: $(".ui-edit"), + view: $(".ui-view"), + both: $(".ui-both") + }, + area: { + edit: $(".ui-edit-area"), + view: $(".ui-view-area"), + codemirror: $(".ui-edit-area .CodeMirror"), + markdown: $(".ui-view-area .markdown-body") + } +}; + +//page actions +var opts = { + lines: 11, // The number of lines to draw + length: 20, // The length of each line + width: 2, // The line thickness + radius: 30, // The radius of the inner circle + corners: 0, // Corner roundness (0..1) + rotate: 0, // The rotation offset + direction: 1, // 1: clockwise, -1: counterclockwise + color: '#000', // #rgb or #rrggbb or array of colors + speed: 1.1, // Rounds per second + trail: 60, // Afterglow percentage + shadow: false, // Whether to render a shadow + hwaccel: true, // Whether to use hardware acceleration + className: 'spinner', // The CSS class to assign to the spinner + zIndex: 2e9, // The z-index (defaults to 2000000000) + top: '50%', // Top position relative to parent + left: '50%' // Left position relative to parent +}; +var spinner = new Spinner(opts).spin(ui.spinner[0]); +//when page ready +$(document).ready(function () { + checkResponsive(); + changeMode(currentMode); + /* we need this only on touch devices */ + if (isTouchDevice) { + /* cache dom references */ + var $body = jQuery('body'); + + /* bind events */ + $(document) + .on('focus', 'textarea, input', function() { + $body.addClass('fixfixed'); + }) + .on('blur', 'textarea, input', function() { + $body.removeClass('fixfixed'); + }); + } +}); +//when page resize +$(window).resize(function () { + checkResponsive(); +}); +//768-792px have a gap +function checkResponsive() { + visibleXS = $(".visible-xs").is(":visible"); + visibleSM = $(".visible-sm").is(":visible"); + visibleMD = $(".visible-md").is(":visible"); + visibleLG = $(".visible-lg").is(":visible"); + if (visibleXS && currentMode == modeType.both) + if (editor.hasFocus()) + changeMode(modeType.edit); + else + changeMode(modeType.view); +} + +function showStatus(type, num) { + currentStatus = type; + var shortStatus = ui.toolbar.shortStatus; + var status = ui.toolbar.status; + var label = $(''); + var fa = $(''); + var msg = ""; + var shortMsg = ""; + + shortStatus.html(""); + status.html(""); + + switch (currentStatus) { + case statusType.connected: + label.addClass(statusType.connected.label); + fa.addClass(statusType.connected.fa); + msg = statusType.connected.msg; + break; + case statusType.online: + label.addClass(statusType.online.label); + fa.addClass(statusType.online.fa); + shortMsg = " " + num; + msg = statusType.online.msg + num; + break; + case statusType.offline: + label.addClass(statusType.offline.label); + fa.addClass(statusType.offline.fa); + msg = statusType.offline.msg; + break; + } + + label.append(fa); + var shortLabel = label.clone(); + + shortLabel.append(" " + shortMsg); + shortStatus.append(shortLabel); + + label.append(" " + msg); + status.append(label); +} + +function toggleMode() { + switch(currentMode) { + case modeType.edit: + changeMode(modeType.view); + break; + case modeType.view: + changeMode(modeType.edit); + break; + case modeType.both: + changeMode(modeType.view); + break; + } +} + +function changeMode(type) { + saveInfo(); + if (type) + currentMode = type; + var responsiveClass = "col-lg-6 col-md-6 col-sm-6"; + var scrollClass = "ui-scrollable"; + ui.area.codemirror.removeClass(scrollClass); + ui.area.edit.removeClass(responsiveClass); + ui.area.view.removeClass(scrollClass); + ui.area.view.removeClass(responsiveClass); + switch (currentMode) { + case modeType.edit: + ui.area.edit.show(); + ui.area.view.hide(); + if (!editShown) { + editor.refresh(); + editShown = true; + } + break; + case modeType.view: + ui.area.edit.hide(); + ui.area.view.show(); + break; + case modeType.both: + ui.area.codemirror.addClass(scrollClass); + ui.area.edit.addClass(responsiveClass).show(); + ui.area.view.addClass(scrollClass); + ui.area.view.addClass(responsiveClass).show(); + break; + } + if (currentMode != modeType.view && visibleLG) { + editor.focus(); + editor.refresh(); + } else { + editor.getInputField().blur(); + } + if (changeMode != modeType.edit) + updateView(); + restoreInfo(); + + ui.toolbar.both.removeClass("active"); + ui.toolbar.edit.removeClass("active"); + ui.toolbar.view.removeClass("active"); + var modeIcon = ui.toolbar.mode.find('i'); + modeIcon.removeClass('fa-toggle-on').removeClass('fa-toggle-off'); + if (ui.area.edit.is(":visible") && ui.area.view.is(":visible")) { //both + ui.toolbar.both.addClass("active"); + modeIcon.addClass('fa-eye'); + } else if (ui.area.edit.is(":visible")) { //edit + ui.toolbar.edit.addClass("active"); + modeIcon.addClass('fa-toggle-off'); + } else if (ui.area.view.is(":visible")) { //view + ui.toolbar.view.addClass("active"); + modeIcon.addClass('fa-toggle-on'); + } +} + +//button actions +var noteId = window.location.pathname.split('/')[1]; +var url = window.location.origin + '/' + noteId; +//pretty +ui.toolbar.pretty.attr("href", url + "/pretty"); +//download +//markdown +ui.toolbar.download.markdown.click(function() { + var filename = renderFilename(ui.area.markdown) + '.md'; + var markdown = editor.getValue(); + var blob = new Blob([markdown], {type: "text/markdown;charset=utf-8"}); + saveAs(blob, filename); +}); +//save to dropbox +ui.toolbar.save.dropbox.click(function() { + var filename = renderFilename(ui.area.markdown) + '.md'; + var options = { + files: [ + {'url': url + "/download", 'filename': filename} + ] + }; + Dropbox.save(options); +}); +//import from dropbox +ui.toolbar.import.dropbox.click(function() { + var options = { + success: function(files) { + ui.spinner.show(); + var url = files[0].link; + importFromUrl(url); + }, + linkType: "direct", + multiselect: false, + extensions: ['.md', '.html'] + }; + Dropbox.choose(options); +}); +//import from clipboard +ui.toolbar.import.clipboard.click(function() { + //na +}); +//fix for wrong autofocus +$('#clipboardModal').on('shown.bs.modal', function() { + $('#clipboardModal').blur(); +}); +$("#clipboardModalClear").click(function() { + $("#clipboardModalContent").html(''); +}); +$("#clipboardModalConfirm").click(function() { + var data = $("#clipboardModalContent").html(); + if(data) { + parseToEditor(data); + $('#clipboardModal').modal('hide'); + $("#clipboardModalContent").html(''); + } +}); +function parseToEditor(data) { + var parsed = toMarkdown(data); + if(parsed) + editor.replaceRange(parsed, {line:0, ch:0}, {line:editor.lastLine(), ch:editor.lastLine().length}, '+input'); +} +function importFromUrl(url) { + //console.log(url); + if(url == null) return; + if(!isValidURL(url)) { + alert('Not valid URL :('); + return; + } + $.ajax({ + method: "GET", + url: url, + success: function(data) { + parseToEditor(data); + }, + error: function() { + alert('Import failed :('); + }, + complete: function() { + ui.spinner.hide(); + } + }); +} +function isValidURL(str) { + var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol + '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name + '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address + '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path + '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string + '(\\#[-a-z\\d_]*)?$','i'); // fragment locator + if(!pattern.test(str)) { + return false; + } else { + return true; + } +} +//mode +ui.toolbar.mode.click(function () { + toggleMode(); +}); +//edit +ui.toolbar.edit.click(function () { + changeMode(modeType.edit); +}); +//view +ui.toolbar.view.click(function () { + changeMode(modeType.view); +}); +//both +ui.toolbar.both.click(function () { + changeMode(modeType.both); +}); + +//socket.io actions +var socket = io.connect(); +socket.on('info', function (data) { + console.error(data); + location.href = "./404.html"; +}); +socket.on('disconnect', function (data) { + showStatus(statusType.offline); + if (loaded) { + saveInfo(); + lastInfo.history = editor.getHistory(); + } + if (!editor.getOption('readOnly')) + editor.setOption('readOnly', true); +}); +socket.on('connect', function (data) { + showStatus(statusType.connected); + socket.emit('version'); +}); +socket.on('version', function (data) { + if (data != version) + location.reload(true); +}); +socket.on('refresh', function (data) { + saveInfo(); + + var body = data.body; + body = LZString.decompressFromBase64(body); + if (body) + editor.setValue(body); + else + editor.setValue(""); + + if (!loaded) { + editor.clearHistory(); + ui.spinner.hide(); + ui.content.fadeIn(); + changeMode(); + loaded = true; + } else { + if (LZString.compressToBase64(editor.getValue()) !== data.body) + editor.clearHistory(); + else { + if (lastInfo.history) + editor.setHistory(lastInfo.history); + } + lastInfo.history = null; + } + + updateView(); + + if (editor.getOption('readOnly')) + editor.setOption('readOnly', false); + + restoreInfo(); +}); +socket.on('change', function (data) { + data = LZString.decompressFromBase64(data); + data = JSON.parse(data); + editor.replaceRange(data.text, data.from, data.to, "ignoreHistory"); + isDirty = true; + clearTimeout(finishChangeTimer); + finishChangeTimer = setTimeout(finishChange, finishChangeDelay); +}); +socket.on('online users', function (data) { + if (debug) + console.debug(data); + showStatus(statusType.online, data.count); + $('.other-cursors').html(''); + for(var i = 0; i < data.users.length; i++) { + var user = data.users[i]; + if(user.id != socket.id) + buildCursor(user.id, user.color, user.cursor); + } +}); +socket.on('cursor focus', function (data) { + if(debug) + console.debug(data); + var cursor = $('#' + data.id); + if(cursor.length > 0) { + cursor.fadeIn(); + } else { + if(data.id != socket.id) + buildCursor(data.id, data.color, data.cursor); + } +}); +socket.on('cursor activity', function (data) { + if(debug) + console.debug(data); + if(data.id != socket.id) + buildCursor(data.id, data.color, data.cursor); +}); +socket.on('cursor blur', function (data) { + if(debug) + console.debug(data); + var cursor = $('#' + data.id); + if(cursor.length > 0) { + cursor.fadeOut(); + } +}); +function emitUserStatus() { + checkIfAuth( + function (data) { + socket.emit('user status', {login:true}); + }, + function () { + socket.emit('user status', {login:false}); + } + ); +} + +function buildCursor(id, color, pos) { + if(!pos) return; + if ($('.other-cursors').length <= 0) { + $("
    ").insertAfter('.CodeMirror-cursors'); + } + if ($('#' + id).length <= 0) { + var cursor = $('
     
    '); + //console.debug(pos); + cursor.attr('data-line', pos.line); + cursor.attr('data-ch', pos.ch); + var coord = editor.charCoords(pos, 'windows'); + cursor[0].style.left = coord.left + 'px'; + cursor[0].style.top = coord.top + 'px'; + cursor[0].style.height = '18px'; + cursor[0].style.borderLeft = '2px solid ' + color; + $('.other-cursors').append(cursor); + cursor.hide().fadeIn(); + } else { + var cursor = $('#' + id); + cursor.attr('data-line', pos.line); + cursor.attr('data-ch', pos.ch); + var coord = editor.charCoords(pos, 'windows'); + cursor.stop(true).css('opacity', 1).animate({"left":coord.left, "top":coord.top}, cursorAnimatePeriod); + //cursor[0].style.left = coord.left + 'px'; + //cursor[0].style.top = coord.top + 'px'; + cursor[0].style.height = '18px'; + cursor[0].style.borderLeft = '2px solid ' + color; + } +} + +//editor actions +editor.on('beforeChange', function (cm, change) { + if (debug) + console.debug(change); +}); +editor.on('change', function (i, op) { + if (debug) + console.debug(op); + if (op.origin != 'setValue' && op.origin != 'ignoreHistory') { + socket.emit('change', LZString.compressToBase64(JSON.stringify(op))); + } + isDirty = true; + clearTimeout(doneTypingTimer); + doneTypingTimer = setTimeout(doneTyping, doneTypingDelay); +}); +editor.on('focus', function (cm) { + socket.emit('cursor focus', editor.getCursor()); +}); +var cursorActivityTimer = null; +editor.on('cursorActivity', function (cm) { + clearTimeout(cursorActivityTimer); + cursorActivityTimer = setTimeout(cursorActivity, cursorActivityDelay); +}); +function cursorActivity() { + socket.emit('cursor activity', editor.getCursor()); +} +editor.on('blur', function (cm) { + socket.emit('cursor blur'); +}); + +function saveInfo() { + var left = $(document.body).scrollLeft(); + var top = $(document.body).scrollTop(); + switch (currentMode) { + case modeType.edit: + lastInfo.edit.scroll.left = left; + lastInfo.edit.scroll.top = top; + break; + case modeType.view: + lastInfo.view.scroll.left = left; + lastInfo.view.scroll.top = top; + break; + case modeType.both: + lastInfo.edit.scroll = editor.getScrollInfo(); + lastInfo.view.scroll.left = ui.area.view.scrollLeft(); + lastInfo.view.scroll.top = ui.area.view.scrollTop(); + break; + } + lastInfo.edit.cursor = editor.getCursor(); + lastInfo.needRestore = true; +} + +function restoreInfo() { + if (lastInfo.needRestore) { + var line = lastInfo.edit.cursor.line; + var ch = lastInfo.edit.cursor.ch; + editor.setCursor(line, ch); + + switch (currentMode) { + case modeType.edit: + $(document.body).scrollLeft(lastInfo.edit.scroll.left); + $(document.body).scrollTop(lastInfo.edit.scroll.top); + break; + case modeType.view: + $(document.body).scrollLeft(lastInfo.view.scroll.left); + $(document.body).scrollTop(lastInfo.view.scroll.top); + break; + case modeType.both: + var left = lastInfo.edit.scroll.left; + var top = lastInfo.edit.scroll.top; + editor.scrollIntoView(); + editor.scrollTo(left, top); + ui.area.view.scrollLeft(lastInfo.view.scroll.left); + ui.area.view.scrollTop(lastInfo.view.scroll.top); + break; + } + + lastInfo.needRestore = false; + } +} + +//view actions +var doneTypingTimer = null; +var finishChangeTimer = null; +var input = editor.getInputField(); +//user is "finished typing," do something +function doneTyping() { + updateView(); + var value = editor.getValue(); + socket.emit('refresh', LZString.compressToBase64(value)); +} + +function finishChange() { + updateView(); +} + +var lastResult = null; + +function updateView() { + if (currentMode == modeType.edit || !isDirty) return; + var value = editor.getValue(); + var result = postProcess(md.render(value)).children().toArray(); + //ui.area.markdown.html(result); + //finishView(ui.area.markdown); + partialUpdate(result, lastResult, ui.area.markdown.children().toArray()); + lastResult = $(result).clone(true); + finishView(ui.area.view); + writeHistory(ui.area.markdown); + isDirty = false; + // reset lines mapping cache on content update + scrollMap = null; + emitUserStatus(); +} + +function partialUpdate(src, tar, des) { + if (!src || src.length == 0 || !tar || tar.length == 0 || !des || des.length == 0) { + ui.area.markdown.html(src); + return; + } + if (src.length == tar.length) { //same length + for (var i = 0; i < src.length; i++) { + copyAttribute(src[i], des[i], 'data-startline'); + copyAttribute(src[i], des[i], 'data-endline'); + var rawSrc = cloneAndRemoveDataAttr(src[i]); + var rawTar = cloneAndRemoveDataAttr(tar[i]); + if (rawSrc.outerHTML != rawTar.outerHTML) { + //console.log(rawSrc); + //console.log(rawTar); + $(des[i]).replaceWith(src[i]); + } + } + } else { //diff length + var start = 0; + var end = 0; + //find diff start position + for (var i = 0; i < tar.length; i++) { + copyAttribute(src[i], des[i], 'data-startline'); + copyAttribute(src[i], des[i], 'data-endline'); + var rawSrc = cloneAndRemoveDataAttr(src[i]); + var rawTar = cloneAndRemoveDataAttr(tar[i]); + if (!rawSrc || !rawTar || rawSrc.outerHTML != rawTar.outerHTML) { + start = i; + break; + } + } + //find diff end position + var srcEnd = 0; + var tarEnd = 0; + for (var i = 0; i < src.length; i++) { + copyAttribute(src[i], des[i], 'data-startline'); + copyAttribute(src[i], des[i], 'data-endline'); + var rawSrc = cloneAndRemoveDataAttr(src[i]); + var rawTar = cloneAndRemoveDataAttr(tar[i]); + if (!rawSrc || !rawTar || rawSrc.outerHTML != rawTar.outerHTML) { + start = i; + break; + } + } + //tar end + for (var i = 1; i <= tar.length; i++) { + var srcLength = src.length; + var tarLength = tar.length; + copyAttribute(src[srcLength - i], des[srcLength - i], 'data-startline'); + copyAttribute(src[srcLength - i], des[srcLength - i], 'data-endline'); + var rawSrc = cloneAndRemoveDataAttr(src[srcLength - i]); + var rawTar = cloneAndRemoveDataAttr(tar[tarLength - i]); + if (!rawSrc || !rawTar || rawSrc.outerHTML != rawTar.outerHTML) { + tarEnd = tar.length - i; + break; + } + } + //src end + for (var i = 1; i <= src.length; i++) { + var srcLength = src.length; + var tarLength = tar.length; + copyAttribute(src[srcLength - i], des[srcLength - i], 'data-startline'); + copyAttribute(src[srcLength - i], des[srcLength - i], 'data-endline'); + var rawSrc = cloneAndRemoveDataAttr(src[srcLength - i]); + var rawTar = cloneAndRemoveDataAttr(tar[tarLength - i]); + if (!rawSrc || !rawTar || rawSrc.outerHTML != rawTar.outerHTML) { + srcEnd = src.length - i; + break; + } + } + //check if tar end overlap tar start + var overlap = 0; + for (var i = start; i >= 0; i--) { + var rawTarStart = cloneAndRemoveDataAttr(tar[i-1]); + var rawTarEnd = cloneAndRemoveDataAttr(tar[tarEnd+1+start-i]); + if(rawTarStart && rawTarEnd && rawTarStart.outerHTML == rawTarEnd.outerHTML) + overlap++; + else + break; + } + if(debug) + console.log('overlap:' + overlap); + //show diff content + if(debug) { + console.log('start:' + start); + console.log('tarEnd:' + tarEnd); + console.log('srcEnd:' + srcEnd); + console.log('des[start]:' + des[start]); + } + tarEnd += overlap; + srcEnd += overlap; + //add new element + var newElements = ""; + for (var j = start; j <= srcEnd; j++) { + if(debug) + srcChanged += src[j].outerHTML; + newElements += src[j].outerHTML; + } + if(newElements && des[start]) { + $(newElements).insertBefore(des[start]); + } else { + $(newElements).insertAfter(des[des.length-1]); + } + if(debug) + console.log(srcChanged); + //remove old element + if(debug) + var tarChanged = ""; + for (var j = start; j <= tarEnd; j++) { + if(debug) + tarChanged += tar[j].outerHTML; + if(des[j]) + des[j].remove(); + } + if(debug) { + console.log(tarChanged); + var srcChanged = ""; + } + } +} + +function cloneAndRemoveDataAttr(el) { + if(!el) return; + var rawEl = $(el).clone(true)[0]; + rawEl.removeAttribute('data-startline'); + rawEl.removeAttribute('data-endline'); + return rawEl; +} + +function copyAttribute(src, des, attr) { + if (src && src.getAttribute(attr) && des) + des.setAttribute(attr, src.getAttribute(attr)); +} + +// +// Inject line numbers for sync scroll. Notes: +// +// - We track only headings and paragraphs on first level. That's enougth. +// - Footnotes content causes jumps. Level limit filter it automatically. +// +md.renderer.rules.paragraph_open = function (tokens, idx) { + var line; + if (tokens[idx].lines && tokens[idx].level === 0) { + var startline = tokens[idx].lines[0] + 1; + var endline = tokens[idx].lines[1]; + return '

    '; + } + return ''; +}; + +md.renderer.rules.heading_open = function (tokens, idx) { + var line; + if (tokens[idx].lines && tokens[idx].level === 0) { + var startline = tokens[idx].lines[0] + 1; + var endline = tokens[idx].lines[1]; + return ''; + } + return ''; +}; + +editor.on('scroll', _.debounce(syncScrollToView, syncScrollDelay)); +//ui.area.view.on('scroll', _.debounce(syncScrollToEdit, 50)); +var scrollMap; +// Build offsets for each line (lines can be wrapped) +// That's a bit dirty to process each line everytime, but ok for demo. +// Optimizations are required only for big texts. +function buildScrollMap() { + var i, offset, nonEmptyList, pos, a, b, lineHeightMap, linesCount, + acc, sourceLikeDiv, textarea = ui.area.codemirror, + _scrollMap; + + sourceLikeDiv = $('

    ').css({ + position: 'absolute', + visibility: 'hidden', + height: 'auto', + width: editor.getScrollInfo().clientWidth, + 'font-size': textarea.css('font-size'), + 'font-family': textarea.css('font-family'), + 'line-height': textarea.css('line-height'), + 'white-space': textarea.css('white-space') + }).appendTo('body'); + + offset = ui.area.view.scrollTop() - ui.area.view.offset().top; + _scrollMap = []; + nonEmptyList = []; + lineHeightMap = []; + + acc = 0; + editor.getValue().split('\n').forEach(function (str) { + var h, lh; + + lineHeightMap.push(acc); + + if (str.length === 0) { + acc++; + return; + } + + sourceLikeDiv.text(str); + h = parseFloat(sourceLikeDiv.css('height')); + lh = parseFloat(sourceLikeDiv.css('line-height')); + acc += Math.round(h / lh); + }); + sourceLikeDiv.remove(); + lineHeightMap.push(acc); + linesCount = acc; + + for (i = 0; i < linesCount; i++) { + _scrollMap.push(-1); + } + + nonEmptyList.push(0); + _scrollMap[0] = 0; + + ui.area.markdown.find('.part').each(function (n, el) { + var $el = $(el), + t = $el.data('startline'); + if (t === '') { + return; + } + t = lineHeightMap[t]; + if (t !== 0) { + nonEmptyList.push(t); + } + _scrollMap[t] = Math.round($el.offset().top + offset); + }); + + nonEmptyList.push(linesCount); + _scrollMap[linesCount] = ui.area.view[0].scrollHeight; + + pos = 0; + for (i = 1; i < linesCount; i++) { + if (_scrollMap[i] !== -1) { + pos++; + continue; + } + + a = nonEmptyList[pos]; + b = nonEmptyList[pos + 1]; + _scrollMap[i] = Math.round((_scrollMap[b] * (i - a) + _scrollMap[a] * (b - i)) / (b - a)); + } + + return _scrollMap; +} + +function syncScrollToView() { + var lineNo, posTo; + var scrollInfo = editor.getScrollInfo(); + if (!scrollMap) { + scrollMap = buildScrollMap(); + } + lineNo = Math.floor(scrollInfo.top / editor.defaultTextHeight()); + posTo = scrollMap[lineNo]; + ui.area.view.stop(true).animate({scrollTop: posTo}, scrollAnimatePeriod); +} + +function syncScrollToEdit() { + var lineNo, posTo; + if (!scrollMap) { + scrollMap = buildScrollMap(); + } + var top = ui.area.view.scrollTop(); + lineNo = closestIndex(top, scrollMap); + posTo = lineNo * editor.defaultTextHeight(); + editor.scrollTo(0, posTo); +} + +function closestIndex(num, arr) { + var curr = arr[0]; + var index = 0; + var diff = Math.abs(num - curr); + for (var val = 0; val < arr.length; val++) { + var newdiff = Math.abs(num - arr[val]); + if (newdiff < diff) { + diff = newdiff; + curr = arr[val]; + index = val; + } + } + return index; +} \ No newline at end of file diff --git a/public/js/unused.js b/public/js/unused.js new file mode 100644 index 00000000..4ff5b280 --- /dev/null +++ b/public/js/unused.js @@ -0,0 +1,45 @@ + + //parse Youtube + result.find(".youtube").each(function (key, value) { + if (!$(value).attr('videoid')) return; + setSizebyAttr(this, this); + var icon = ''; + $(this).append(icon); + var videoid = $(value).attr('videoid'); + var thumbnail_src = '//img.youtube.com/vi/' + videoid + '/hqdefault.jpg'; + $(value).css('background-image', 'url(' + thumbnail_src + ')'); + $(this).click(function () { + imgPlayiframe(this, '//www.youtube.com/embed/'); + }); + }); + //parse vimeo + result.find(".vimeo").each(function (key, value) { + if (!$(value).attr('videoid')) return; + setSizebyAttr(this, this); + var icon = ''; + $(this).append(icon); + var videoid = $(value).attr('videoid'); + $.ajax({ + type: 'GET', + url: 'http://vimeo.com/api/v2/video/' + videoid + '.json', + jsonp: 'callback', + dataType: 'jsonp', + success: function (data) { + var thumbnail_src = data[0].thumbnail_large; + $(value).css('background-image', 'url(' + thumbnail_src + ')'); + } + }); + $(this).click(function () { + imgPlayiframe(this, '//player.vimeo.com/video/'); + }); + }); + //todo list + var lis = result[0].getElementsByTagName('li'); + for (var i = 0; i < lis.length; i++) { + var html = lis[i].innerHTML; + if (/^\s*\[[x ]\]\s*/.test(html)) { + lis[i].innerHTML = html.replace(/^\s*\[ \]\s*/, '') + .replace(/^\s*\[x\]\s*/, ''); + lis[i].setAttribute('class', 'task-list-item'); + } + } \ No newline at end of file -- cgit v1.2.3