From 8031c31bc3dca9bba844b2757b69b8b6e0dd2a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bartelme=C3=9F?= Date: Sun, 19 Feb 2012 03:16:42 +0100 Subject: [PATCH 01/98] more compact code for exposed functions in ace2.js --- static/js/ace.js | 78 ++++++++++++++---------------------------------- 1 file changed, 23 insertions(+), 55 deletions(-) diff --git a/static/js/ace.js b/static/js/ace.js index 049309101..63367e3f9 100644 --- a/static/js/ace.js +++ b/static/js/ace.js @@ -49,8 +49,7 @@ function Ace2Editor() { var that = this; var args = arguments; - - function action() + var action = function() { func.apply(that, args); } @@ -71,78 +70,47 @@ function Ace2Editor() function doActionsPendingInit() { - for (var i = 0; i < actionsPendingInit.length; i++) - { - actionsPendingInit[i](); - } + $.each(actionsPendingInit, function(i,fn){ + fn() + }); actionsPendingInit = []; } - + ace2.registry[info.id] = info; - editor.importText = pendingInit(function(newCode, undoable) - { - info.ace_importText(newCode, undoable); - }); - editor.importAText = pendingInit(function(newCode, apoolJsonObj, undoable) - { - info.ace_importAText(newCode, apoolJsonObj, undoable); + // The following functions (prefixed by 'ace_') are exposed by editor, but + // execution is delayed until init is complete + var aceFunctionsPendingInit = ['importText', 'importAText', 'focus', + 'setEditable', 'getFormattedCode', 'setOnKeyPress', 'setOnKeyDown', + 'setNotifyDirty', 'setProperty', 'setBaseText', 'setBaseAttributedText', + 'applyChangesToBase', 'applyPreparedChangesetToBase', + 'setUserChangeNotificationCallback', 'setAuthorInfo', + 'setAuthorSelectionRange', 'callWithAce', 'execCommand', 'replaceRange']; + + $.each(aceFunctionsPendingInit, function(i,fnName){ + var prefix = 'ace_'; + var name = prefix + fnName; + editor[fnName] = pendingInit(function(){ + info[prefix + fnName].apply(this, arguments); + }); }); + editor.exportText = function() { if (!loaded) return "(awaiting init)\n"; return info.ace_exportText(); }; + editor.getFrame = function() { return info.frame || null; }; - editor.focus = pendingInit(function() - { - info.ace_focus(); - }); - editor.setEditable = pendingInit(function(newVal) - { - info.ace_setEditable(newVal); - }); - editor.getFormattedCode = function() - { - return info.ace_getFormattedCode(); - }; - editor.setOnKeyPress = pendingInit(function(handler) - { - info.ace_setOnKeyPress(handler); - }); - editor.setOnKeyDown = pendingInit(function(handler) - { - info.ace_setOnKeyDown(handler); - }); - editor.setNotifyDirty = pendingInit(function(handler) - { - info.ace_setNotifyDirty(handler); - }); - - editor.setProperty = pendingInit(function(key, value) - { - info.ace_setProperty(key, value); - }); + editor.getDebugProperty = function(prop) { return info.ace_getDebugProperty(prop); }; - editor.setBaseText = pendingInit(function(txt) - { - info.ace_setBaseText(txt); - }); - editor.setBaseAttributedText = pendingInit(function(atxt, apoolJsonObj) - { - info.ace_setBaseAttributedText(atxt, apoolJsonObj); - }); - editor.applyChangesToBase = pendingInit(function(changes, optAuthor, apoolJsonObj) - { - info.ace_applyChangesToBase(changes, optAuthor, apoolJsonObj); - }); // prepareUserChangeset: // Returns null if no new changes or ACE not ready. Otherwise, bundles up all user changes // to the latest base text into a Changeset, which is returned (as a string if encodeAsString). From 99fb567a3d72039f5a798baf33b61f24b2b22bcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bartelme=C3=9F?= Date: Sun, 19 Feb 2012 12:15:42 +0100 Subject: [PATCH 02/98] removed parenModule as it is entirely unused since getCharType() always returns an emtpy string --- static/js/ace2_inner.js | 194 ++-------------------------------------- 1 file changed, 6 insertions(+), 188 deletions(-) diff --git a/static/js/ace2_inner.js b/static/js/ace2_inner.js index d21135743..5963609d1 100644 --- a/static/js/ace2_inner.js +++ b/static/js/ace2_inner.js @@ -460,11 +460,11 @@ function OUTER(gscope) submitOldEvent(cs.editEvent); if (cs.domClean && cs.type != "setup") { - if (cs.isUserChange) - { - if (cs.repChanged) parenModule.notifyChange(); - else parenModule.notifyTick(); - } + // if (cs.isUserChange) + // { + // if (cs.repChanged) parenModule.notifyChange(); + // else parenModule.notifyTick(); + // } recolorModule.recolorLines(); if (cs.selectionAffected) { @@ -570,182 +570,6 @@ function OUTER(gscope) return module; })(); - var parenModule = (function() - { - var module = {}; - module.notifyTick = function() - { - handleFlashing(false); - }; - module.notifyChange = function() - { - handleFlashing(true); - }; - module.shouldNormalizeOnChar = function(c) - { - if (parenFlashRep.active) - { - // avoid highlight style from carrying on to typed text - return true; - } - c = String.fromCharCode(c); - return !!(bracketMap[c]); - } - - var parenFlashRep = { - active: false, - whichChars: null, - whichLineKeys: null, - expireTime: null - }; - var bracketMap = { - '(': 1, - ')': -1, - '[': 2, - ']': -2, - '{': 3, - '}': -3 - }; - var bracketRegex = /[{}\[\]()]/g; - - function handleFlashing(docChanged) - { - function getSearchRange(aroundLoc) - { - var rng = getVisibleCharRange(); - var d = 100; // minimum radius - var e = 3000; // maximum radius; - if (rng[0] > aroundLoc - d) rng[0] = aroundLoc - d; - if (rng[0] < aroundLoc - e) rng[0] = aroundLoc - e; - if (rng[0] < 0) rng[0] = 0; - if (rng[1] < aroundLoc + d) rng[1] = aroundLoc + d; - if (rng[1] > aroundLoc + e) rng[1] = aroundLoc + e; - if (rng[1] > rep.lines.totalWidth()) rng[1] = rep.lines.totalWidth(); - return rng; - } - - function findMatchingVisibleBracket(startLoc, forwards) - { - var rng = getSearchRange(startLoc); - var str = rep.alltext.substring(rng[0], rng[1]); - var bstr = str.replace(bracketRegex, '('); // handy for searching - var loc = startLoc - rng[0]; - var bracketState = []; - var foundParen = false; - var goodParen = false; - - function nextLoc() - { - if (loc < 0) return; - if (forwards) loc++; - else loc--; - if (loc < 0 || loc >= str.length) loc = -1; - if (loc >= 0) - { - if (forwards) loc = bstr.indexOf('(', loc); - else loc = bstr.lastIndexOf('(', loc); - } - } - while ((!foundParen) && (loc >= 0)) - { - if (getCharType(loc + rng[0]) == "p") - { - var b = bracketMap[str.charAt(loc)]; // -1, 1, -2, 2, -3, 3 - var into = forwards; - var typ = b; - if (typ < 0) - { - into = !into; - typ = -typ; - } - if (into) bracketState.push(typ); - else - { - var recent = bracketState.pop(); - if (recent != typ) - { - foundParen = true; - goodParen = false; - } - else if (bracketState.length == 0) - { - foundParen = true; - goodParen = true; - } - } - } - //console.log(bracketState.toSource()); - if ((!foundParen) && (loc >= 0)) nextLoc(); - } - if (!foundParen) return null; - return { - chr: (loc + rng[0]), - good: goodParen - }; - } - - var r = parenFlashRep; - var charsToHighlight = null; - var linesToUnhighlight = null; - if (r.active && (docChanged || (now() > r.expireTime))) - { - linesToUnhighlight = r.whichLineKeys; - r.active = false; - } - if ((!r.active) && docChanged && isCaret() && caretColumn() > 0) - { - var caret = caretDocChar(); - if (caret > 0 && getCharType(caret - 1) == "p") - { - var charBefore = rep.alltext.charAt(caret - 1); - if (bracketMap[charBefore]) - { - var lookForwards = (bracketMap[charBefore] > 0); - var findResult = findMatchingVisibleBracket(caret - 1, lookForwards); - if (findResult) - { - var mateLoc = findResult.chr; - var mateGood = findResult.good; - r.active = true; - charsToHighlight = {}; - charsToHighlight[caret - 1] = 'flash'; - charsToHighlight[mateLoc] = (mateGood ? 'flash' : 'flashbad'); - r.whichLineKeys = []; - r.whichLineKeys.push(getLineKeyForOffset(caret - 1)); - r.whichLineKeys.push(getLineKeyForOffset(mateLoc)); - r.expireTime = now() + 4000; - newlyActive = true; - } - } - } - - } - if (linesToUnhighlight) - { - recolorLineByKey(linesToUnhighlight[0]); - recolorLineByKey(linesToUnhighlight[1]); - } - if (r.active && charsToHighlight) - { - function f(txt, cls, next, ofst) - { - var flashClass = charsToHighlight[ofst]; - if (cls) - { - next(txt, cls + " " + flashClass); - } - else next(txt, cls); - } - for (var c in charsToHighlight) - { - recolorLinesInRange((+c), (+c) + 1, null, f); - } - } - } - - return module; - })(); - function dispose() { disposed = true; @@ -1548,12 +1372,6 @@ function OUTER(gscope) } } - - function getCharType(charIndex) - { - return ''; - } - var observedChanges; function clearObservedChanges() @@ -3968,7 +3786,7 @@ function OUTER(gscope) } else if (type == "keypress") { - if ((!specialHandled) && parenModule.shouldNormalizeOnChar(charCode)) + if ((!specialHandled) && false /*parenModule.shouldNormalizeOnChar(charCode)*/) { idleWorkTimer.atMost(0); } From 3cd7bd0dd18b32df90298a756b0ca425e01aaf57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bartelme=C3=9F?= Date: Sun, 19 Feb 2012 12:34:24 +0100 Subject: [PATCH 03/98] Since ace2_inner.js is already scoped by require-kernel, function OUTER is pretty useless --- static/js/ace2_inner.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/static/js/ace2_inner.js b/static/js/ace2_inner.js index 5963609d1..9e353e200 100644 --- a/static/js/ace2_inner.js +++ b/static/js/ace2_inner.js @@ -49,8 +49,7 @@ var newSkipList = require('/skiplist').newSkipList; var undoModule = require('/undomodule').undoModule; var makeVirtualLineView = require('/virtual_lines').makeVirtualLineView; -function OUTER(gscope) -{ + var DEBUG = false; //$$ build script replaces the string "var DEBUG=true;//$$" with "var DEBUG=false;" // changed to false @@ -5708,10 +5707,4 @@ function OUTER(gscope) lineNumbersShown--; } } - } - -}; - -OUTER(this); - -exports.OUTER = OUTER; // This is probably unimportant. + } \ No newline at end of file From 77dbe4646e1f88030bbf605ed4ee811dc3fb95de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bartelme=C3=9F?= Date: Sun, 19 Feb 2012 12:40:13 +0100 Subject: [PATCH 04/98] binarySearch is never used --- static/js/ace2_inner.js | 1 - 1 file changed, 1 deletion(-) diff --git a/static/js/ace2_inner.js b/static/js/ace2_inner.js index 9e353e200..4f936e59b 100644 --- a/static/js/ace2_inner.js +++ b/static/js/ace2_inner.js @@ -32,7 +32,6 @@ var isArray = Ace2Common.isArray; var browser = Ace2Common.browser; var getAssoc = Ace2Common.getAssoc; var setAssoc = Ace2Common.setAssoc; -var binarySearch = Ace2Common.binarySearch; var binarySearchInfinite = Ace2Common.binarySearchInfinite; var htmlPrettyEscape = Ace2Common.htmlPrettyEscape; var map = Ace2Common.map; From a66e01a08fd8c82cc1976a26b9435fde3ac06fb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bartelme=C3=9F?= Date: Sun, 19 Feb 2012 14:11:32 +0100 Subject: [PATCH 05/98] moving noop and identity helper functions to ace2_common --- static/js/ace2_common.js | 5 +++++ static/js/ace2_inner.js | 10 ++-------- static/js/domline.js | 23 ++++++++++------------- 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/static/js/ace2_common.js b/static/js/ace2_common.js index b4c72a92f..0f8195fa7 100644 --- a/static/js/ace2_common.js +++ b/static/js/ace2_common.js @@ -141,6 +141,9 @@ function htmlPrettyEscape(str) return Security.escapeHTML(str).replace(/\r?\n/g, '\\n'); } +var noop = function(){}; +var identity = function(x){return x}; + exports.isNodeText = isNodeText; exports.object = object; exports.extend = extend; @@ -155,3 +158,5 @@ exports.binarySearch = binarySearch; exports.binarySearchInfinite = binarySearchInfinite; exports.htmlPrettyEscape = htmlPrettyEscape; exports.map = map; +exports.noop = noop; +exports.identity = identity; diff --git a/static/js/ace2_inner.js b/static/js/ace2_inner.js index 4f936e59b..de04c0674 100644 --- a/static/js/ace2_inner.js +++ b/static/js/ace2_inner.js @@ -21,6 +21,7 @@ */ var Ace2Common = require('/ace2_common'); + // Extract useful method defined in the other module. var isNodeText = Ace2Common.isNodeText; var object = Ace2Common.object; @@ -35,6 +36,7 @@ var setAssoc = Ace2Common.setAssoc; var binarySearchInfinite = Ace2Common.binarySearchInfinite; var htmlPrettyEscape = Ace2Common.htmlPrettyEscape; var map = Ace2Common.map; +var noop = Ace2Common.noop; var makeChangesetTracker = require('/changesettracker').makeChangesetTracker; var colorutils = require('/colorutils').colorutils; @@ -145,14 +147,6 @@ var makeVirtualLineView = require('/virtual_lines').makeVirtualLineView; }; } - function noop() - {} - - function identity(x) - { - return x; - } - // "dmesg" is for displaying messages in the in-page output pane // visible when "?djs=1" is appended to the pad URL. It generally // remains a no-op unless djs is enabled, but we make a habit of diff --git a/static/js/domline.js b/static/js/domline.js index 15528bf7a..3074c9e93 100644 --- a/static/js/domline.js +++ b/static/js/domline.js @@ -27,16 +27,13 @@ // requires: undefined var Security = require('/security'); +var Ace2Common = require('/ace2_common'); var plugins = require('/plugins').plugins; -var map = require('/ace2_common').map; +var map = Ace2Common.map; +var noop = Ace2Common.noop; +var identity = Ace2Common.identity; var domline = {}; -domline.noop = function() -{}; -domline.identity = function(x) -{ - return x; -}; domline.addToLineClass = function(lineClass, cls) { @@ -60,11 +57,11 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument) { var result = { node: null, - appendSpan: domline.noop, - prepareForAdd: domline.noop, - notifyAdded: domline.noop, - clearSpans: domline.noop, - finishUpdate: domline.noop, + appendSpan: noop, + prepareForAdd: noop, + notifyAdded: noop, + clearSpans: noop, + finishUpdate: noop, lineMarker: 0 }; @@ -91,7 +88,7 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument) { return domline.processSpaces(s, doesWrap); } - var identity = domline.identity; + var perTextNodeProcess = (doesWrap ? identity : processSpaces); var perHtmlLineProcess = (doesWrap ? processSpaces : identity); var lineClass = 'ace-line'; From 5313053d2deac6b33a6a85dcd01ffe926a2a206e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bartelme=C3=9F?= Date: Sun, 19 Feb 2012 14:18:52 +0100 Subject: [PATCH 06/98] even more compact code for exposed functions in ace2.js --- static/js/ace.js | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/static/js/ace.js b/static/js/ace.js index 63367e3f9..6c7bb84e2 100644 --- a/static/js/ace.js +++ b/static/js/ace.js @@ -125,24 +125,6 @@ function Ace2Editor() if (!loaded) return null; return info.ace_prepareUserChangeset(); }; - editor.applyPreparedChangesetToBase = pendingInit( - - function() - { - info.ace_applyPreparedChangesetToBase(); - }); - editor.setUserChangeNotificationCallback = pendingInit(function(callback) - { - info.ace_setUserChangeNotificationCallback(callback); - }); - editor.setAuthorInfo = pendingInit(function(author, authorInfo) - { - info.ace_setAuthorInfo(author, authorInfo); - }); - editor.setAuthorSelectionRange = pendingInit(function(author, start, end) - { - info.ace_setAuthorSelectionRange(author, start, end); - }); editor.getUnhandledErrors = function() { @@ -151,19 +133,7 @@ function Ace2Editor() return info.ace_getUnhandledErrors(); }; - editor.callWithAce = pendingInit(function(fn, callStack, normalize) - { - return info.ace_callWithAce(fn, callStack, normalize); - }); - editor.execCommand = pendingInit(function(cmd, arg1) - { - info.ace_execCommand(cmd, arg1); - }); - editor.replaceRange = pendingInit(function(start, end, text) - { - info.ace_replaceRange(start, end, text); - }); function sortFilesByEmbeded(files) { var embededFiles = []; From fb879576e192f036806ab15e1792474e002cd358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bartelme=C3=9F?= Date: Sun, 19 Feb 2012 14:28:51 +0100 Subject: [PATCH 07/98] replaced noop in skiplist with ace2common implementation --- static/js/skiplist.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/static/js/skiplist.js b/static/js/skiplist.js index 385f08f0d..190bc55b9 100644 --- a/static/js/skiplist.js +++ b/static/js/skiplist.js @@ -21,7 +21,7 @@ */ - +var noop = require('./ace2_common').noop; function newSkipList() @@ -41,9 +41,6 @@ function newSkipList() }; } - function noop() - {} - // if there are N elements in the skiplist, "start" is element -1 and "end" is element N var start = { key: null, From 3c4b4af43dcc6f2246b61db68210a8e25fcdf5f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bartelme=C3=9F?= Date: Sun, 19 Feb 2012 14:30:08 +0100 Subject: [PATCH 08/98] removed recolor module since it wasn't used --- static/js/ace2_inner.js | 50 +---------------------------------------- 1 file changed, 1 insertion(+), 49 deletions(-) diff --git a/static/js/ace2_inner.js b/static/js/ace2_inner.js index de04c0674..9e2271ca1 100644 --- a/static/js/ace2_inner.js +++ b/static/js/ace2_inner.js @@ -457,7 +457,6 @@ var makeVirtualLineView = require('/virtual_lines').makeVirtualLineView; // if (cs.repChanged) parenModule.notifyChange(); // else parenModule.notifyTick(); // } - recolorModule.recolorLines(); if (cs.selectionAffected) { updateBrowserSelectionFromRep(); @@ -514,54 +513,7 @@ var makeVirtualLineView = require('/virtual_lines').makeVirtualLineView; { return rep.lines.atOffset(charOffset).key; } - - var recolorModule = (function() - { - var dirtyLineKeys = {}; - - var module = {}; - module.setCharNeedsRecoloring = function(offset) - { - if (offset >= rep.alltext.length) - { - offset = rep.alltext.length - 1; - } - dirtyLineKeys[getLineKeyForOffset(offset)] = true; - } - - module.setCharRangeNeedsRecoloring = function(offset1, offset2) - { - if (offset1 >= rep.alltext.length) - { - offset1 = rep.alltext.length - 1; - } - if (offset2 >= rep.alltext.length) - { - offset2 = rep.alltext.length - 1; - } - var firstEntry = rep.lines.atOffset(offset1); - var lastKey = rep.lines.atOffset(offset2).key; - dirtyLineKeys[lastKey] = true; - var entry = firstEntry; - while (entry && entry.key != lastKey) - { - dirtyLineKeys[entry.key] = true; - entry = rep.lines.next(entry); - } - } - - module.recolorLines = function() - { - for (var k in dirtyLineKeys) - { - recolorLineByKey(k); - } - dirtyLineKeys = {}; - } - - return module; - })(); - + function dispose() { disposed = true; From ce8d60e32c137e2937fae2fa30d17ccc30d4d18b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bartelme=C3=9F?= Date: Sun, 19 Feb 2012 14:30:57 +0100 Subject: [PATCH 09/98] remamed to Ace2Inner() and made it more classlike --- static/js/ace2_inner.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/static/js/ace2_inner.js b/static/js/ace2_inner.js index 9e2271ca1..9e5f2a3d5 100644 --- a/static/js/ace2_inner.js +++ b/static/js/ace2_inner.js @@ -51,7 +51,7 @@ var undoModule = require('/undomodule').undoModule; var makeVirtualLineView = require('/virtual_lines').makeVirtualLineView; - +function Ace2Inner(){ var DEBUG = false; //$$ build script replaces the string "var DEBUG=true;//$$" with "var DEBUG=false;" // changed to false var isSetUp = false; @@ -5652,4 +5652,8 @@ var makeVirtualLineView = require('/virtual_lines').makeVirtualLineView; lineNumbersShown--; } } - } \ No newline at end of file + } + +}; + +exports.editor = new Ace2Inner(); \ No newline at end of file From 7e7646b5176c06caa8a4719788d0ebe93e67dc7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bartelme=C3=9F?= Date: Sun, 19 Feb 2012 14:52:24 +0100 Subject: [PATCH 10/98] make jshint a bit more happier --- static/js/ace2_inner.js | 154 +++++++++++++++++++++------------------- 1 file changed, 80 insertions(+), 74 deletions(-) diff --git a/static/js/ace2_inner.js b/static/js/ace2_inner.js index 9e5f2a3d5..e00b486df 100644 --- a/static/js/ace2_inner.js +++ b/static/js/ace2_inner.js @@ -122,13 +122,13 @@ function Ace2Inner(){ iframePadRight = 0; var console = (DEBUG && window.console); + if (!window.console) { var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; console = {}; for (var i = 0; i < names.length; ++i) - console[names[i]] = function() - {}; + console[names[i]] = noop; //console.error = function(str) { alert(str); }; } @@ -330,7 +330,7 @@ function Ace2Inner(){ editorInfo.ace_getRep = function() { return rep; - } + }; var currentCallStack = null; @@ -547,7 +547,7 @@ function Ace2Inner(){ alineLength += o.chars; if (opIter.hasNext()) { - if (o.lines != 0) error(); + if (o.lines !== 0) error(); } else { @@ -865,9 +865,9 @@ function Ace2Inner(){ editorInfo.ace_callWithAce = function(fn, callStack, normalize) { var wrapper = function() - { - return fn(editorInfo); - } + { + return fn(editorInfo); + }; @@ -878,7 +878,7 @@ function Ace2Inner(){ { editorInfo.ace_fastIncorp(9); wrapper1(); - } + }; } if (callStack !== undefined) @@ -889,7 +889,7 @@ function Ace2Inner(){ { return wrapper(); } - } + }; editorInfo.ace_setProperty = function(key, value) { @@ -943,7 +943,7 @@ function Ace2Inner(){ { setClassPresence(root, "rtl", !! value); } - } + }; editorInfo.ace_setBaseText = function(txt) { @@ -1042,12 +1042,12 @@ function Ace2Inner(){ lastElapsed = elapsed; return false; } - } + }; isTimeUp.elapsed = function() { return now() - startTime; - } + }; return isTimeUp; } @@ -1105,7 +1105,7 @@ function Ace2Inner(){ { unschedule(); } - } + }; } function fastIncorp(n) @@ -1297,7 +1297,7 @@ function Ace2Inner(){ } var text = lineEntry.text; var width = lineEntry.width; // text.length+1 - if (text.length == 0) + if (text.length === 0) { // allow getLineStyleFilter to set line-div styles var func = linestylefilter.getLineStyleFilter( @@ -1424,17 +1424,19 @@ function Ace2Inner(){ var p = PROFILER("getSelection", false); var selection = getSelection(); p.end(); + + function topLevel(n) + { + if ((!n) || n == root) return null; + while (n.parentNode != root) + { + n = n.parentNode; + } + return n; + } + if (selection) { - function topLevel(n) - { - if ((!n) || n == root) return null; - while (n.parentNode != root) - { - n = n.parentNode; - } - return n; - } var node1 = topLevel(selection.startPoint.node); var node2 = topLevel(selection.endPoint.node); if (node1) observeChangesAroundNode(node1); @@ -1507,7 +1509,7 @@ function Ace2Inner(){ { a = dirtyRanges[j][0]; b = dirtyRanges[j][1]; - if (!((a == 0 || getCleanNodeByKey(rep.lines.atIndex(a - 1).key)) && (b == rep.lines.length() || getCleanNodeByKey(rep.lines.atIndex(b).key)))) + if (!((a === 0 || getCleanNodeByKey(rep.lines.atIndex(a - 1).key)) && (b == rep.lines.length() || getCleanNodeByKey(rep.lines.atIndex(b).key)))) { dirtyRangesCheckOut = false; break; @@ -1548,7 +1550,7 @@ function Ace2Inner(){ var range = dirtyRanges[i]; a = range[0]; b = range[1]; - var firstDirtyNode = (((a == 0) && root.firstChild) || getCleanNodeByKey(rep.lines.atIndex(a - 1).key).nextSibling); + var firstDirtyNode = (((a === 0) && root.firstChild) || getCleanNodeByKey(rep.lines.atIndex(a - 1).key).nextSibling); firstDirtyNode = (firstDirtyNode && isNodeDirty(firstDirtyNode) && firstDirtyNode); var lastDirtyNode = (((b == rep.lines.length()) && root.lastChild) || getCleanNodeByKey(rep.lines.atIndex(b).key).previousSibling); lastDirtyNode = (lastDirtyNode && isNodeDirty(lastDirtyNode) && lastDirtyNode); @@ -1846,7 +1848,7 @@ function Ace2Inner(){ function handleReturnIndentation() { // on return, indent to level of previous line - if (isCaret() && caretColumn() == 0 && caretLine() > 0) + if (isCaret() && caretColumn() === 0 && caretLine() > 0) { var lineNum = caretLine(); var thisLine = rep.lines.atIndex(lineNum); @@ -1928,10 +1930,10 @@ function Ace2Inner(){ var lineNode = lineEntry.lineNode; var n = lineNode; var after = false; - if (charsLeft == 0) + if (charsLeft === 0) { var index = 0; - if (browser.msie && line == (rep.lines.length() - 1) && lineNode.childNodes.length == 0) + if (browser.msie && line == (rep.lines.length() - 1) && lineNode.childNodes.length === 0) { // best to stay at end of last empty div in IE index = 1; @@ -1995,7 +1997,7 @@ function Ace2Inner(){ // assuming the point is not in a dirty node. if (point.node == root) { - if (point.index == 0) + if (point.index === 0) { return [0, 0]; } @@ -2033,7 +2035,7 @@ function Ace2Inner(){ n = parNode; } } - if (n.id == "") console.debug("BAD"); + if (n.id === "") console.debug("BAD"); if (n.firstChild && isBlockElement(n.firstChild)) { col += 1; // lineMarker @@ -2258,7 +2260,7 @@ function Ace2Inner(){ function performDocumentReplaceCharRange(startChar, endChar, newText) { - if (startChar == endChar && newText.length == 0) + if (startChar == endChar && newText.length === 0) { return; } @@ -2275,7 +2277,7 @@ function Ace2Inner(){ endChar--; newText = '\n' + newText.substring(0, newText.length - 1); } - else if (newText.length == 0) + else if (newText.length === 0) { // a delete at end startChar--; @@ -2293,8 +2295,8 @@ function Ace2Inner(){ function performDocumentReplaceRange(start, end, newText) { - if (start == undefined) start = rep.selStart; - if (end == undefined) end = rep.selEnd; + if (start === undefined) start = rep.selStart; + if (end === undefined) end = rep.selEnd; //dmesg(String([start.toSource(),end.toSource(),newText.toSource()])); // start[0]: <--- start[1] --->CCCCCCCCCCC\n @@ -2534,7 +2536,7 @@ function Ace2Inner(){ spliceEnd--; commonEnd++; } - if (shortOldText.length == 0 && spliceStart == rep.alltext.length && shortNewText.length > 0) + if (shortOldText.length === 0 && spliceStart == rep.alltext.length && shortNewText.length > 0) { // inserting after final newline, bad spliceStart--; @@ -2542,7 +2544,7 @@ function Ace2Inner(){ shortNewText = '\n' + shortNewText.slice(0, -1); shiftFinalNewlineToBeforeNewText = true; } - if (spliceEnd == rep.alltext.length && shortOldText.length > 0 && shortNewText.length == 0) + if (spliceEnd == rep.alltext.length && shortOldText.length > 0 && shortNewText.length === 0) { // deletion at end of rep.alltext if (rep.alltext.charAt(spliceStart - 1) == '\n') @@ -2554,7 +2556,7 @@ function Ace2Inner(){ } } - if (!(shortOldText.length == 0 && shortNewText.length == 0)) + if (!(shortOldText.length === 0 && shortNewText.length === 0)) { var oldDocText = rep.alltext; var oldLen = oldDocText.length; @@ -2562,15 +2564,15 @@ function Ace2Inner(){ var spliceStartLine = rep.lines.indexOfOffset(spliceStart); var spliceStartLineStart = rep.lines.offsetOfIndex(spliceStartLine); - function startBuilder() + var startBuilder = function() { var builder = Changeset.builder(oldLen); builder.keep(spliceStartLineStart, spliceStartLine); builder.keep(spliceStart - spliceStartLineStart); return builder; - } + }; - function eachAttribRun(attribs, func /*(startInNewText, endInNewText, attribs)*/ ) + var eachAttribRun = function(attribs, func /*(startInNewText, endInNewText, attribs)*/ ) { var attribsIter = Changeset.opIterator(attribs); var textIndex = 0; @@ -2586,7 +2588,7 @@ function Ace2Inner(){ } textIndex = nextIndex; } - } + }; var justApplyStyles = (shortNewText == shortOldText); var theChangeset; @@ -2786,7 +2788,7 @@ function Ace2Inner(){ var newEndIter = attribIterator(newARuns, true); while (commonEnd < minLen) { - if (commonEnd == 0) + if (commonEnd === 0) { // assume newline in common oldEndIter(); @@ -2929,10 +2931,11 @@ function Ace2Inner(){ lineClass = ''; // non-null to cause update }; - function writeClass() + var writeClass = function() { if (lineClass !== null) lineElem.className = lineClass; - } + }; + result.prepareForAdd = writeClass; result.finishUpdate = writeClass; result.getInnerHTML = function() @@ -3159,7 +3162,7 @@ function Ace2Inner(){ } } - if (N == 0) + if (N === 0) { p.cancel(); if (!isConsecutive(0)) @@ -3291,16 +3294,18 @@ function Ace2Inner(){ idleWorkTimer.atMost(200); }); + function isLink(n) + { + return (n.tagName || '').toLowerCase() == "a" && n.href; + } + // only want to catch left-click if ((!evt.ctrlKey) && (evt.button != 2) && (evt.button != 3)) { // find A tag with HREF - function isLink(n) - { - return (n.tagName || '').toLowerCase() == "a" && n.href; - } + var n = evt.target; while (n && n.parentNode && !isLink(n)) { @@ -3375,7 +3380,7 @@ function Ace2Inner(){ var firstLine, lastLine; firstLine = rep.selStart[0]; - lastLine = Math.max(firstLine, rep.selEnd[0] - ((rep.selEnd[1] == 0) ? 1 : 0)); + lastLine = Math.max(firstLine, rep.selEnd[0] - ((rep.selEnd[1] === 0) ? 1 : 0)); var mods = []; for (var n = firstLine; n <= lastLine; n++) @@ -3509,7 +3514,7 @@ function Ace2Inner(){ //separated. If it returns null, it means that the list was not cut, try //from the current one. var line = caretLine(); - if(line != -1 && renumberList(line+1)==null) + if(line != -1 && renumberList(line+1) === null) { renumberList(line); } @@ -3747,7 +3752,7 @@ function Ace2Inner(){ } // Is part of multi-keystroke international character on Firefox Mac - var isFirefoxHalfCharacter = (browser.mozilla && evt.altKey && charCode == 0 && keyCode == 0); + var isFirefoxHalfCharacter = (browser.mozilla && evt.altKey && charCode === 0 && keyCode === 0); // Is part of multi-keystroke international character on Safari Mac var isSafariHalfCharacter = (browser.safari && evt.altKey && keyCode == 229); @@ -3846,7 +3851,7 @@ function Ace2Inner(){ { var text = entry.text; var content; - if (text.length == 0) + if (text.length === 0) { content = '--'; } @@ -3912,27 +3917,27 @@ function Ace2Inner(){ var selectionParent = origSelectionRange.parentElement(); if (selectionParent.ownerDocument != doc) return null; - function newRange() + var newRange = function() { return doc.body.createTextRange(); - } + }; - function rangeForElementNode(nd) + var rangeForElementNode = function(nd) { var rng = newRange(); // doesn't work on text nodes rng.moveToElementText(nd); return rng; - } + }; - function pointFromCollapsedRange(rng) + var pointFromCollapsedRange = function(rng) { var parNode = rng.parentElement(); var elemBelow = -1; var elemAbove = parNode.childNodes.length; var rangeWithin = rangeForElementNode(parNode); - if (rng.compareEndPoints("StartToStart", rangeWithin) == 0) + if (rng.compareEndPoints("StartToStart", rangeWithin) === 0) { return { node: parNode, @@ -3940,7 +3945,7 @@ function Ace2Inner(){ maxIndex: 1 }; } - else if (rng.compareEndPoints("EndToEnd", rangeWithin) == 0) + else if (rng.compareEndPoints("EndToEnd", rangeWithin) === 0) { if (isBlockElement(parNode) && parNode.nextSibling) { @@ -3958,7 +3963,7 @@ function Ace2Inner(){ maxIndex: 1 }; } - else if (parNode.childNodes.length == 0) + else if (parNode.childNodes.length === 0) { return { node: parNode, @@ -4067,9 +4072,10 @@ function Ace2Inner(){ index: tn.nodeValue.length, maxIndex: tn.nodeValue.length }; - } + }; + var selection = {}; - if (origSelectionRange.compareEndPoints("StartToEnd", origSelectionRange) == 0) + if (origSelectionRange.compareEndPoints("StartToEnd", origSelectionRange) === 0) { // collapsed var pnt = pointFromCollapsedRange(origSelectionRange); @@ -4089,10 +4095,10 @@ function Ace2Inner(){ selection.startPoint = pointFromCollapsedRange(start); selection.endPoint = pointFromCollapsedRange(end); /*if ((!selection.startPoint.node.isText) && (!selection.endPoint.node.isText)) { - console.log(selection.startPoint.node.uniqueId()+","+ - selection.startPoint.index+" / "+ - selection.endPoint.node.uniqueId()+","+ - selection.endPoint.index); + console.log(selection.startPoint.node.uniqueId()+","+ + selection.startPoint.index+" / "+ + selection.endPoint.node.uniqueId()+","+ + selection.endPoint.index); }*/ } return selection; @@ -4135,7 +4141,7 @@ function Ace2Inner(){ maxIndex: n.nodeValue.length }; } - else if (childCount == 0) + else if (childCount === 0) { return { node: n, @@ -4261,7 +4267,7 @@ function Ace2Inner(){ setCollapsedBefore(s, n); s.move("character", point.index); } - else if (point.index == 0) + else if (point.index === 0) { setCollapsedBefore(s, n); } @@ -4349,7 +4355,7 @@ function Ace2Inner(){ while (p.node.childNodes.length > 0) { //&& (p.node == root || p.node.parentNode == root)) { - if (p.index == 0) + if (p.index === 0) { p.node = p.node.firstChild; p.maxIndex = nodeMaxIndex(p.node); @@ -4452,7 +4458,7 @@ function Ace2Inner(){ function fixView() { // calling this method repeatedly should be fast - if (getInnerWidth() == 0 || getInnerHeight() == 0) + if (getInnerWidth() === 0 || getInnerHeight() === 0) { return; } @@ -4871,7 +4877,7 @@ function Ace2Inner(){ } if (!isNodeText(node)) { - if (index == 0) return leftOf(node); + if (index === 0) return leftOf(node); else return rightOf(node); } else @@ -5152,7 +5158,7 @@ function Ace2Inner(){ var firstLine, lastLine; firstLine = rep.selStart[0]; - lastLine = Math.max(firstLine, rep.selEnd[0] - ((rep.selEnd[1] == 0) ? 1 : 0)); + lastLine = Math.max(firstLine, rep.selEnd[0] - ((rep.selEnd[1] === 0) ? 1 : 0)); var allLinesAreList = true; for (var n = firstLine; n <= lastLine; n++) @@ -5362,7 +5368,7 @@ function Ace2Inner(){ // move by "paragraph", a feature that Firefox lacks but IE and Safari both have if (up) { - if (focusCaret[1] == 0 && canChangeLines) + if (focusCaret[1] === 0 && canChangeLines) { focusCaret[0]--; focusCaret[1] = 0; From 9ede14a546731e692640a408c2b5bdb07d2c2c59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bartelme=C3=9F?= Date: Sun, 19 Feb 2012 15:02:54 +0100 Subject: [PATCH 11/98] drop embedding of JS/CSS files in ace.js. May result in a little performance drop but makes code much smaller --- node/utils/Minify.js | 74 +------------------- static/js/ace.js | 158 +++++++++++++++---------------------------- 2 files changed, 56 insertions(+), 176 deletions(-) diff --git a/node/utils/Minify.js b/node/utils/Minify.js index 859ee07ae..baeaee688 100644 --- a/node/utils/Minify.js +++ b/node/utils/Minify.js @@ -213,72 +213,6 @@ function _handle(req, res, jsFilename, jsFiles) { } } -// find all includes in ace.js and embed them. -function getAceFile(callback) { - fs.readFile(JS_DIR + 'ace.js', "utf8", function(err, data) { - if(ERR(err, callback)) return; - - // Find all includes in ace.js and embed them - var founds = data.match(/\$\$INCLUDE_[a-zA-Z_]+\([a-zA-Z0-9.\/_"-]+\)/gi); - if (!settings.minify) { - founds = []; - } - founds.push('$$INCLUDE_JS("../static/js/require-kernel.js")'); - - data += ';\n'; - data += 'Ace2Editor.EMBEDED = Ace2Editor.EMBEDED || {};\n'; - - //go trough all includes - async.forEach(founds, function (item, callback) { - var filename = item.match(/"([^"]*)"/)[1]; - var type = item.match(/INCLUDE_([A-Z]+)/)[1]; - var shortFilename = (filename.match(/^..\/static\/js\/(.*)$/, '')||[])[1]; - - //read the included files - if (shortFilename) { - if (shortFilename == 'require-kernel.js') { - // the kernel isn’t actually on the file system. - handleEmbed(null, requireDefinition()); - } else { - var contents = ''; - tarCode(tar[shortFilename] || shortFilename - , function (content) { - contents += content; - } - , function () { - handleEmbed(null, contents); - } - ); - } - } else { - fs.readFile(ROOT_DIR + filename, "utf8", handleEmbed); - } - - function handleEmbed(error, data_) { - if (error) { - return; // Don't bother to include it. - } - if (settings.minify) { - if (type == "JS") { - try { - data_ = compressJS([data_]); - } catch (e) { - // Ignore, include uncompresseed, which will break in browser. - } - } else { - data_ = compressCSS([data_]); - } - } - data += 'Ace2Editor.EMBEDED[' + JSON.stringify(filename) + '] = ' - + JSON.stringify(data_) + ';\n'; - callback(); - } - }, function(error) { - callback(error, data); - }); - }); -} - exports.requireDefinition = requireDefinition; function requireDefinition() { return 'var require = ' + RequireKernel.kernelSource + ';\n'; @@ -288,12 +222,8 @@ function tarCode(jsFiles, write, callback) { write('require.define({'); var initialEntry = true; async.forEach(jsFiles, function (filename, callback){ - if (filename == 'ace.js') { - getAceFile(handleFile); - } else { - fs.readFile(JS_DIR + filename, "utf8", handleFile); - } - + fs.readFile(JS_DIR + filename, "utf8", handleFile); + function handleFile(err, data) { if(ERR(err, callback)) return; var srcPath = JSON.stringify('/' + filename); diff --git a/static/js/ace.js b/static/js/ace.js index 6c7bb84e2..63b1e61fe 100644 --- a/static/js/ace.js +++ b/static/js/ace.js @@ -133,74 +133,6 @@ function Ace2Editor() return info.ace_getUnhandledErrors(); }; - - - function sortFilesByEmbeded(files) { - var embededFiles = []; - var remoteFiles = []; - - if (Ace2Editor.EMBEDED) { - for (var i = 0, ii = files.length; i < ii; i++) { - var file = files[i]; - if (Object.prototype.hasOwnProperty.call(Ace2Editor.EMBEDED, file)) { - embededFiles.push(file); - } else { - remoteFiles.push(file); - } - } - } else { - remoteFiles = files; - } - - return {embeded: embededFiles, remote: remoteFiles}; - } - function pushRequireScriptTo(buffer) { - var KERNEL_SOURCE = '../static/js/require-kernel.js'; - var KERNEL_BOOT = 'require.setRootURI("../minified/");\nrequire.setGlobalKeyPath("require");' - if (Ace2Editor.EMBEDED && Ace2Editor.EMBEDED[KERNEL_SOURCE]) { - buffer.push(''); + iframeHTML.push('\ -'); - pushScriptsTo(iframeHTML); - + iframeHTML.push('require.define("/plugins", null);'); + iframeHTML.push('require.define("/plugins.js", function (require, exports, module) {'); + iframeHTML.push('module.exports = parent.parent.require("/plugins");'); + iframeHTML.push('});'); + iframeHTML.push('<\/script>'); + + // Require ace2 + iframeHTML.push(''); + iframeHTML.push(' -
-
New Pad

or create/open a Pad with the name
-
+
+
+
New Pad
+
or create/open a Pad with the name
+ - - + + +
+ - + - + '); - iframeHTML.push(''); - iframeHTML.push('\ +'); + pushScriptsTo(iframeHTML); + iframeHTML.push(''); iframeHTML.push(' '); - editor.iframeHTML = iframeHTML.join('\n'); - // Expose myself to global for my child frame. var thisFunctionsName = "ChildAccessibleAce2Editor"; (function () {return this}())[thisFunctionsName] = Ace2Editor; - - var outerScript = 'editorId = "' + info.id + '"; editorInfo = parent.' + thisFunctionsName + '.registry[editorId]; ' + - 'window.onload = function()' + - '{ window.onload = null; setTimeout' + '(function() ' + - '{ var iframe = document.createElement("IFRAME"); ' + - 'iframe.scrolling = "no"; var outerdocbody = document.getElementById("outerdocbody"); ' + - 'iframe.frameBorder = 0; iframe.allowTransparency = true; ' + // for IE - 'outerdocbody.insertBefore(iframe, outerdocbody.firstChild); ' + - 'iframe.ace_outerWin = window; ' + - 'var doc = iframe.contentWindow.document; doc.open();doc.write(editorInfo.editor.iframeHTML); doc.close();'+ - 'readyFunc = function() { editorInfo.onEditorReady(); readyFunc = null; editorInfo = null; };' + - '}, 0); }'; - - - // Build HTML of editor iFrame; - var outerHTML = [doctype, '']; - outerHTML.push(''); - outerHTML.push(''); - outerHTML.push(''] + + var includedCSS = []; + var $$INCLUDE_CSS = function(filename) {includedCSS.push(filename)}; + $$INCLUDE_CSS("../static/css/iframe_editor.css"); + $$INCLUDE_CSS("../static/css/pad.css"); + $$INCLUDE_CSS("../static/custom/pad.css"); + pushStyleTagsFor(outerHTML, includedCSS); // bizarrely, in FF2, a file with no "external" dependencies won't finish loading properly // (throbs busy while typing) @@ -244,7 +295,6 @@ function Ace2Editor() document.getElementById(containerId).appendChild(outerFrame); var editorDocument = outerFrame.contentWindow.document; - editorDocument.open(); editorDocument.write(outerHTML.join('')); From c3f728b2ed8592973bfca992485bb11e1678f089 Mon Sep 17 00:00:00 2001 From: Peter 'Pita' Martischka Date: Sun, 26 Feb 2012 16:13:07 +0100 Subject: [PATCH 68/98] Revert "drop embedding of JS/CSS files in ace.js. May result in a little performance drop but makes code much smaller" This reverts commit 9ede14a546731e692640a408c2b5bdb07d2c2c59. --- node/utils/Minify.js | 74 +++++++++++++++++++- static/js/ace.js | 158 ++++++++++++++++++++++++++++--------------- 2 files changed, 176 insertions(+), 56 deletions(-) diff --git a/node/utils/Minify.js b/node/utils/Minify.js index baeaee688..859ee07ae 100644 --- a/node/utils/Minify.js +++ b/node/utils/Minify.js @@ -213,6 +213,72 @@ function _handle(req, res, jsFilename, jsFiles) { } } +// find all includes in ace.js and embed them. +function getAceFile(callback) { + fs.readFile(JS_DIR + 'ace.js', "utf8", function(err, data) { + if(ERR(err, callback)) return; + + // Find all includes in ace.js and embed them + var founds = data.match(/\$\$INCLUDE_[a-zA-Z_]+\([a-zA-Z0-9.\/_"-]+\)/gi); + if (!settings.minify) { + founds = []; + } + founds.push('$$INCLUDE_JS("../static/js/require-kernel.js")'); + + data += ';\n'; + data += 'Ace2Editor.EMBEDED = Ace2Editor.EMBEDED || {};\n'; + + //go trough all includes + async.forEach(founds, function (item, callback) { + var filename = item.match(/"([^"]*)"/)[1]; + var type = item.match(/INCLUDE_([A-Z]+)/)[1]; + var shortFilename = (filename.match(/^..\/static\/js\/(.*)$/, '')||[])[1]; + + //read the included files + if (shortFilename) { + if (shortFilename == 'require-kernel.js') { + // the kernel isn’t actually on the file system. + handleEmbed(null, requireDefinition()); + } else { + var contents = ''; + tarCode(tar[shortFilename] || shortFilename + , function (content) { + contents += content; + } + , function () { + handleEmbed(null, contents); + } + ); + } + } else { + fs.readFile(ROOT_DIR + filename, "utf8", handleEmbed); + } + + function handleEmbed(error, data_) { + if (error) { + return; // Don't bother to include it. + } + if (settings.minify) { + if (type == "JS") { + try { + data_ = compressJS([data_]); + } catch (e) { + // Ignore, include uncompresseed, which will break in browser. + } + } else { + data_ = compressCSS([data_]); + } + } + data += 'Ace2Editor.EMBEDED[' + JSON.stringify(filename) + '] = ' + + JSON.stringify(data_) + ';\n'; + callback(); + } + }, function(error) { + callback(error, data); + }); + }); +} + exports.requireDefinition = requireDefinition; function requireDefinition() { return 'var require = ' + RequireKernel.kernelSource + ';\n'; @@ -222,8 +288,12 @@ function tarCode(jsFiles, write, callback) { write('require.define({'); var initialEntry = true; async.forEach(jsFiles, function (filename, callback){ - fs.readFile(JS_DIR + filename, "utf8", handleFile); - + if (filename == 'ace.js') { + getAceFile(handleFile); + } else { + fs.readFile(JS_DIR + filename, "utf8", handleFile); + } + function handleFile(err, data) { if(ERR(err, callback)) return; var srcPath = JSON.stringify('/' + filename); diff --git a/static/js/ace.js b/static/js/ace.js index 63b1e61fe..6c7bb84e2 100644 --- a/static/js/ace.js +++ b/static/js/ace.js @@ -133,6 +133,74 @@ function Ace2Editor() return info.ace_getUnhandledErrors(); }; + + + function sortFilesByEmbeded(files) { + var embededFiles = []; + var remoteFiles = []; + + if (Ace2Editor.EMBEDED) { + for (var i = 0, ii = files.length; i < ii; i++) { + var file = files[i]; + if (Object.prototype.hasOwnProperty.call(Ace2Editor.EMBEDED, file)) { + embededFiles.push(file); + } else { + remoteFiles.push(file); + } + } + } else { + remoteFiles = files; + } + + return {embeded: embededFiles, remote: remoteFiles}; + } + function pushRequireScriptTo(buffer) { + var KERNEL_SOURCE = '../static/js/require-kernel.js'; + var KERNEL_BOOT = 'require.setRootURI("../minified/");\nrequire.setGlobalKeyPath("require");' + if (Ace2Editor.EMBEDED && Ace2Editor.EMBEDED[KERNEL_SOURCE]) { + buffer.push(''); - iframeHTML.push(''); - iframeHTML.push('\ +'); + pushScriptsTo(iframeHTML); + iframeHTML.push(''); iframeHTML.push(' '); - editor.iframeHTML = iframeHTML.join('\n'); - // Expose myself to global for my child frame. var thisFunctionsName = "ChildAccessibleAce2Editor"; (function () {return this}())[thisFunctionsName] = Ace2Editor; - - var outerScript = 'editorId = "' + info.id + '"; editorInfo = parent.' + thisFunctionsName + '.registry[editorId]; ' + - 'window.onload = function()' + - '{ window.onload = null; setTimeout' + '(function() ' + - '{ var iframe = document.createElement("IFRAME"); ' + - 'iframe.scrolling = "no"; var outerdocbody = document.getElementById("outerdocbody"); ' + - 'iframe.frameBorder = 0; iframe.allowTransparency = true; ' + // for IE - 'outerdocbody.insertBefore(iframe, outerdocbody.firstChild); ' + - 'iframe.ace_outerWin = window; ' + - 'var doc = iframe.contentWindow.document; doc.open();doc.write(editorInfo.editor.iframeHTML); doc.close();'+ - 'readyFunc = function() { editorInfo.onEditorReady(); readyFunc = null; editorInfo = null; };' + - '}, 0); }'; - - - // Build HTML of editor iFrame; - var outerHTML = [doctype, '']; - outerHTML.push(''); - outerHTML.push(''); - outerHTML.push(''] + + var includedCSS = []; + var $$INCLUDE_CSS = function(filename) {includedCSS.push(filename)}; + $$INCLUDE_CSS("../static/css/iframe_editor.css"); + $$INCLUDE_CSS("../static/css/pad.css"); + $$INCLUDE_CSS("../static/custom/pad.css"); + pushStyleTagsFor(outerHTML, includedCSS); // bizarrely, in FF2, a file with no "external" dependencies won't finish loading properly // (throbs busy while typing) @@ -244,7 +295,6 @@ function Ace2Editor() document.getElementById(containerId).appendChild(outerFrame); var editorDocument = outerFrame.contentWindow.document; - editorDocument.open(); editorDocument.write(outerHTML.join('')); From 00c3281a0230cec6bbafd64bcd680974b97e2a03 Mon Sep 17 00:00:00 2001 From: Peter 'Pita' Martischka Date: Sun, 26 Feb 2012 19:59:02 +0100 Subject: [PATCH 69/98] Forbid colons, this Fixes #301 --- node/db/PadManager.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/node/db/PadManager.js b/node/db/PadManager.js index 231aa901f..126826123 100644 --- a/node/db/PadManager.js +++ b/node/db/PadManager.js @@ -43,7 +43,8 @@ var globalPads = { * time, and allow us to "play back" these changes so legacy padIds can be found. */ var padIdTransforms = [ - [/\s+/g, '_'] + [/\s+/g, '_'], + [/:+/g, '_'] ]; /** From 9fe4318e77ea348e3ebd287ede7cc3f41a1191c0 Mon Sep 17 00:00:00 2001 From: Constantin Jucovschi Date: Sun, 26 Feb 2012 18:59:11 +0000 Subject: [PATCH 70/98] more doc update --- static/js/Changeset.js | 174 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 166 insertions(+), 8 deletions(-) diff --git a/static/js/Changeset.js b/static/js/Changeset.js index 42a8f0dc1..81c0c81b2 100644 --- a/static/js/Changeset.js +++ b/static/js/Changeset.js @@ -627,7 +627,11 @@ exports.stringAssembler = function () { }; }; -// "lines" need not be an array as long as it supports certain calls (lines_foo inside). +/** + * This class allows to iterate and modify texts which have several lines + * It is used for applying Changesets on arrays of lines + * Note from prev docs: "lines" need not be an array as long as it supports certain calls (lines_foo inside). + */ exports.textLinesMutator = function (lines) { // Mutates lines, an array of strings, in place. // Mutation operations have the same constraints as exports operations @@ -882,6 +886,21 @@ exports.textLinesMutator = function (lines) { return self; }; +/** + * Function allowing iterating over two Op strings. + * @params in1 {string} first Op string + * @params idx1 {int} integer where 1st iterator should start + * @params in2 {string} second Op string + * @params idx2 {int} integer where 2nd iterator should start + * @params func {function} which decides how 1st or 2nd iterator + * advances. When opX.opcode = 0, iterator X advances to + * next element + * func has signature f(op1, op2, opOut) + * op1 - current operation of the first iterator + * op2 - current operation of the second iterator + * opOut - result operator to be put into Changeset + * @return {string} the integrated changeset + */ exports.applyZip = function (in1, idx1, in2, idx2, func) { var iter1 = exports.opIterator(in1, idx1); var iter2 = exports.opIterator(in2, idx2); @@ -975,6 +994,11 @@ exports.applyToText = function (cs, str) { return assem.toString(); }; +/** + * applies a changeset on an array of lines + * @param CS {Changeset} the changeset to be applied + * @param lines The lines to which the changeset needs to be applied + */ exports.mutateTextLines = function (cs, lines) { var unpacked = exports.unpack(cs); var csIter = exports.opIterator(unpacked.ops); @@ -997,6 +1021,13 @@ exports.mutateTextLines = function (cs, lines) { mut.close(); }; +/** + * Composes two attribute strings (see below) into one. + * @param att1 {string} first attribute string + * @param att2 {string} second attribue string + * @param resultIsMutaton {boolean} + * @param pool {AttribPool} attribute pool + */ exports.composeAttributes = function (att1, att2, resultIsMutation, pool) { // att1 and att2 are strings like "*3*f*1c", asMutation is a boolean. // Sometimes attribute (key,value) pairs are treated as attribute presence @@ -1054,6 +1085,10 @@ exports.composeAttributes = function (att1, att2, resultIsMutation, pool) { return buf.toString(); }; +/** + * Function used as parameter for applyZip to apply a Changeset to an + * attribute + */ exports._slicerZipperFunc = function (attOp, csOp, opOut, pool) { // attOp is the op from the sequence that is being operated on, either an // attribution string or the earlier of two exportss being composed. @@ -1140,6 +1175,12 @@ exports._slicerZipperFunc = function (attOp, csOp, opOut, pool) { } }; +/** + * Applies a Changeset to the attribs string of a AText. + * @param cs {string} Changeset + * @param astr {string} the attribs string of a AText + * @param pool {AttribsPool} the attibutes pool + */ exports.applyToAttribution = function (cs, astr, pool) { var unpacked = exports.unpack(cs); @@ -1248,6 +1289,11 @@ exports.mutateAttributionLines = function (cs, lines, pool) { //dmesg("-> "+lines.toSource()); }; +/** + * joins several Attribution lines + * @param theAlines collection of Attribution lines + * @returns {string} joined Attribution lines + */ exports.joinAttributionLines = function (theAlines) { var assem = exports.mergingOpAssembler(); for (var i = 0; i < theAlines.length; i++) { @@ -1298,10 +1344,20 @@ exports.splitAttributionLines = function (attrOps, text) { return lines; }; +/** + * splits text into lines + * @param {string} text to be splitted + */ exports.splitTextLines = function (text) { return text.match(/[^\n]*(?:\n|[^\n]$)/g); }; +/** + * compose two Changesets + * @param cs1 {Changeset} first Changeset + * @param cs2 {Changeset} second Changeset + * @param pool {AtribsPool} Attribs pool + */ exports.compose = function (cs1, cs2, pool) { var unpacked1 = exports.unpack(cs1); var unpacked2 = exports.unpack(cs2); @@ -1344,10 +1400,14 @@ exports.compose = function (cs1, cs2, pool) { return exports.pack(len1, len3, newOps, bankAssem.toString()); }; +/** + * returns a function that tests if a string of attributes + * (e.g. *3*4) contains a given attribute key,value that + * is already present in the pool. + * @param attribPair array [key,value] of the attribute + * @param pool {AttribPool} Attribute pool + */ exports.attributeTester = function (attribPair, pool) { - // returns a function that tests if a string of attributes - // (e.g. *3*4) contains a given attribute key,value that - // is already present in the pool. if (!pool) { return never; } @@ -1366,10 +1426,27 @@ exports.attributeTester = function (attribPair, pool) { } }; +/** + * creates the identity Changeset of length N + * @param N {int} length of the identity changeset + */ exports.identity = function (N) { return exports.pack(N, N, "", ""); }; + +/** + * creates a Changeset which works on oldFullText and removes text + * from spliceStart to spliceStart+numRemoved and inserts newText + * instead. Also gives possibility to add attributes optNewTextAPairs + * for the new text. + * @param oldFullText {string} old text + * @param spliecStart {int} where splicing starts + * @param numRemoved {int} number of characters to be removed + * @param newText {string} string to be inserted + * @param optNewTextAPairs {string} new pairs to be inserted + * @param pool {AttribPool} Attribution Pool + */ exports.makeSplice = function (oldFullText, spliceStart, numRemoved, newText, optNewTextAPairs, pool) { var oldLen = oldFullText.length; @@ -1390,8 +1467,14 @@ exports.makeSplice = function (oldFullText, spliceStart, numRemoved, newText, op return exports.pack(oldLen, newLen, assem.toString(), newText); }; +/** + * Transforms a changeset into a list of splices in the form + * [startChar, endChar, newText] meaning replace text from + * startChar to endChar with newText + * @param cs Changeset + */ exports.toSplices = function (cs) { - // get a list of splices, [startChar, endChar, newText] + // var unpacked = exports.unpack(cs); var splices = []; @@ -1421,6 +1504,9 @@ exports.toSplices = function (cs) { return splices; }; +/** + * + */ exports.characterRangeFollow = function (cs, startChar, endChar, insertionsAfter) { var newStartChar = startChar; var newEndChar = endChar; @@ -1465,6 +1551,14 @@ exports.characterRangeFollow = function (cs, startChar, endChar, insertionsAfter return [newStartChar, newEndChar]; }; +/** + * Iterate over attributes in a changeset and move them from + * oldPool to newPool + * @param cs {Changeset} Chageset/attribution string to be iterated over + * @param oldPool {AttribPool} old attributes pool + * @param newPool {AttribPool} new attributes pool + * @return {string} the new Changeset + */ exports.moveOpsToNewPool = function (cs, oldPool, newPool) { // works on exports or attribution string var dollarPos = cs.indexOf('$'); @@ -1482,13 +1576,22 @@ exports.moveOpsToNewPool = function (cs, oldPool, newPool) { }) + fromDollar; }; +/** + * create an attribution inserting a text + * @param text {string} text to be inserted + */ exports.makeAttribution = function (text) { var assem = exports.smartOpAssembler(); assem.appendOpWithText('+', text); return assem.toString(); }; -// callable on a exports, attribution string, or attribs property of an op +/** + * Iterates over attributes in exports, attribution string, or attribs property of an op + * and runs function func on them + * @param cs {Changeset} changeset + * @param func {function} function to be called + */ exports.eachAttribNumber = function (cs, func) { var dollarPos = cs.indexOf('$'); if (dollarPos < 0) { @@ -1502,12 +1605,21 @@ exports.eachAttribNumber = function (cs, func) { }); }; -// callable on a exports, attribution string, or attribs property of an op, -// though it may easily create adjacent ops that can be merged. +/** + * Filter attributes which should remain in a Changeset + * callable on a exports, attribution string, or attribs property of an op, + * though it may easily create adjacent ops that can be merged. + * @param cs {Changeset} changeset to be filtered + * @param filter {function} fnc which returns true if an + * attribute X (int) should be kept in the Changeset + */ exports.filterAttribNumbers = function (cs, filter) { return exports.mapAttribNumbers(cs, filter); }; +/** + * does exactly the same as exports.filterAttribNumbers + */ exports.mapAttribNumbers = function (cs, func) { var dollarPos = cs.indexOf('$'); if (dollarPos < 0) { @@ -1542,6 +1654,12 @@ exports.makeAText = function (text, attribs) { }; }; +/** + * Apply a Changeset to a AText + * @param cs {Changeset} Changeset to be applied + * @param atext {AText} + * @param pool {AttribPool} Attribute Pool to add to + */ exports.applyToAText = function (cs, atext, pool) { return { text: exports.applyToText(cs, atext.text), @@ -1549,6 +1667,10 @@ exports.applyToAText = function (cs, atext, pool) { }; }; +/** + * Clones a AText structure + * @param atext {AText} + */ exports.cloneAText = function (atext) { return { text: atext.text, @@ -1556,11 +1678,20 @@ exports.cloneAText = function (atext) { }; }; +/** + * Copies a AText structure from atext1 to atext2 + * @param atext {AText} + */ exports.copyAText = function (atext1, atext2) { atext2.text = atext1.text; atext2.attribs = atext1.attribs; }; +/** + * Append the set of operations from atext to an assembler + * @param atext {AText} + * @param assem Assembler like smartOpAssembler + */ exports.appendATextToAssembler = function (atext, assem) { // intentionally skips last newline char of atext var iter = exports.opIterator(atext.attribs); @@ -1594,6 +1725,11 @@ exports.appendATextToAssembler = function (atext, assem) { } }; +/** + * Creates a clone of a Changeset and it's APool + * @param cs {Changeset} + * @param pool {AtributePool} + */ exports.prepareForWire = function (cs, pool) { var newPool = AttributePoolFactory.createAttributePool();; var newCs = exports.moveOpsToNewPool(cs, pool, newPool); @@ -1603,15 +1739,32 @@ exports.prepareForWire = function (cs, pool) { }; }; +/** + * Checks if a changeset s the identity changeset + */ exports.isIdentity = function (cs) { var unpacked = exports.unpack(cs); return unpacked.ops == "" && unpacked.oldLen == unpacked.newLen; }; +/** + * returns all the values of attributes with a certain key + * in an Op attribs string + * @param attribs {string} Attribute string of a Op + * @param key {string} string to be seached for + * @param pool {AttribPool} attribute pool + */ exports.opAttributeValue = function (op, key, pool) { return exports.attribsAttributeValue(op.attribs, key, pool); }; +/** + * returns all the values of attributes with a certain key + * in an attribs string + * @param attribs {string} Attribute string + * @param key {string} string to be seached for + * @param pool {AttribPool} attribute pool + */ exports.attribsAttributeValue = function (attribs, key, pool) { var value = ''; if (attribs) { @@ -1624,6 +1777,11 @@ exports.attribsAttributeValue = function (attribs, key, pool) { return value; }; +/** + * Creates a Changeset builder for a string with initial + * length oldLen. Allows to add/remove parts of it + * @param oldLen {int} Old length + */ exports.builder = function (oldLen) { var assem = exports.smartOpAssembler(); var o = exports.newOp(); From 4dc86f338224dff193f2bfe131a66e893dee2550 Mon Sep 17 00:00:00 2001 From: John McLear Date: Sun, 26 Feb 2012 21:26:42 +0000 Subject: [PATCH 71/98] fix #507 import showing when it shouldnt --- static/js/pad_impexp.js | 1 + 1 file changed, 1 insertion(+) diff --git a/static/js/pad_impexp.js b/static/js/pad_impexp.js index 6fe42c705..130281bfa 100644 --- a/static/js/pad_impexp.js +++ b/static/js/pad_impexp.js @@ -257,6 +257,7 @@ var padimpexp = (function() $("#exportworda").remove(); $("#exportpdfa").remove(); $("#exportopena").remove(); + $(".importformdiv").remove(); $("#import").html("Import is not available. To enable import please install abiword"); } else if(clientVars.abiwordAvailable == "withoutPDF") From ed8aff22d431dc80926300a019bc9e0439e99370 Mon Sep 17 00:00:00 2001 From: Peter 'Pita' Martischka Date: Mon, 27 Feb 2012 00:22:53 +0100 Subject: [PATCH 72/98] restart abiword on crash and give the user feedback about bad import files --- node/handler/ImportHandler.js | 22 +++++++--- node/utils/Abiword.js | 83 ++++++++++++++++++----------------- static/js/pad_impexp.js | 65 +++++++-------------------- 3 files changed, 75 insertions(+), 95 deletions(-) diff --git a/node/handler/ImportHandler.js b/node/handler/ImportHandler.js index 06a2ce5ca..3dccb8af4 100644 --- a/node/handler/ImportHandler.js +++ b/node/handler/ImportHandler.js @@ -115,7 +115,15 @@ exports.doImport = function(req, res, padId) { var randNum = Math.floor(Math.random()*0xFFFFFFFF); destFile = tempDirectory + "eplite_import_" + randNum + ".txt"; - abiword.convertFile(srcFile, destFile, "txt", callback); + abiword.convertFile(srcFile, destFile, "txt", function(err){ + //catch convert errors + if(err){ + console.warn("Converting Error:", err); + return callback("convertFailed"); + } else { + callback(); + } + }); }, //get the pad object @@ -176,16 +184,18 @@ exports.doImport = function(req, res, padId) } ], function(err) { - //the upload failed, there is nothing we can do, send a 500 - if(err == "uploadFailed") + var status = "ok"; + + //check for known errors and replace the status + if(err == "uploadFailed" || err == "convertFailed") { - res.send(500); - return; + status = err; + err = null; } ERR(err); //close the connection - res.send("ok"); + res.send("", 200); }); } diff --git a/node/utils/Abiword.js b/node/utils/Abiword.js index c53a6ab37..27138e648 100644 --- a/node/utils/Abiword.js +++ b/node/utils/Abiword.js @@ -53,7 +53,7 @@ if(os.type().indexOf("Windows") > -1) abiword.on('exit', function (code) { if(code != 0) { - throw "Abiword died with exit code " + code; + return callback("Abiword died with exit code " + code); } if(stdoutBuffer != "") @@ -75,52 +75,54 @@ if(os.type().indexOf("Windows") > -1) else { //spawn the abiword process - var abiword = spawn(settings.abiword, ["--plugin", "AbiCommand"]); - - //append error messages to the buffer - abiword.stderr.on('data', function (data) - { - stdoutBuffer += data.toString(); - }); - - //throw exceptions if abiword is dieing - abiword.on('exit', function (code) - { - throw "Abiword died with exit code " + code; - }); - - //delegate the processing of stdout to a other function - abiword.stdout.on('data',onAbiwordStdout); - + var abiword; var stdoutCallback = null; - var stdoutBuffer = ""; - var firstPrompt = true; + var spawnAbiword = function (){ + abiword = spawn(settings.abiword, ["--plugin", "AbiCommand"]); + var stdoutBuffer = ""; + var firstPrompt = true; - function onAbiwordStdout(data) - { - //add data to buffer - stdoutBuffer+=data.toString(); - - //we're searching for the prompt, cause this means everything we need is in the buffer - if(stdoutBuffer.search("AbiWord:>") != -1) + //append error messages to the buffer + abiword.stderr.on('data', function (data) { - //filter the feedback message - var err = stdoutBuffer.search("OK") != -1 ? null : stdoutBuffer; + stdoutBuffer += data.toString(); + }); + + //abiword died, let's restart abiword and return an error with the callback + abiword.on('exit', function (code) + { + spawnAbiword(); + stdoutCallback("Abiword died with exit code " + code); + }); + + //delegate the processing of stdout to a other function + abiword.stdout.on('data',function (data) + { + //add data to buffer + stdoutBuffer+=data.toString(); - //reset the buffer - stdoutBuffer = ""; - - //call the callback with the error message - //skip the first prompt - if(stdoutCallback != null && !firstPrompt) + //we're searching for the prompt, cause this means everything we need is in the buffer + if(stdoutBuffer.search("AbiWord:>") != -1) { - stdoutCallback(err); - stdoutCallback = null; + //filter the feedback message + var err = stdoutBuffer.search("OK") != -1 ? null : stdoutBuffer; + + //reset the buffer + stdoutBuffer = ""; + + //call the callback with the error message + //skip the first prompt + if(stdoutCallback != null && !firstPrompt) + { + stdoutCallback(err); + stdoutCallback = null; + } + + firstPrompt = false; } - - firstPrompt = false; - } + }); } + spawnAbiword(); doConvertTask = function(task, callback) { @@ -130,6 +132,7 @@ else stdoutCallback = function (err) { callback(); + console.log("queue continue"); task.callback(err); }; } diff --git a/static/js/pad_impexp.js b/static/js/pad_impexp.js index 6fe42c705..7ec0b3442 100644 --- a/static/js/pad_impexp.js +++ b/static/js/pad_impexp.js @@ -95,11 +95,6 @@ var padimpexp = (function() }, 0); $('#importarrow').stop(true, true).hide(); $('#importstatusball').show(); - - $("#import .importframe").load(function() - { - importDone(); - }); } return ret; } @@ -107,8 +102,6 @@ var padimpexp = (function() function importFailed(msg) { importErrorMessage(msg); - importDone(); - addImportFrames(); } function importDone() @@ -120,6 +113,7 @@ var padimpexp = (function() }, 0); $('#importstatusball').hide(); importClearTimeout(); + addImportFrames(); } function importClearTimeout() @@ -131,11 +125,19 @@ var padimpexp = (function() } } - function importErrorMessage(msg) + function importErrorMessage(status) { + var msg=""; + + if(status === "convertFailed"){ + msg = "We were not able to import this file. Please use a different document format or copy paste manually"; + } else if(status === "uploadFailed"){ + msg = "The upload failed, please try again"; + } + function showError(fade) { - $('#importmessagefail').html('Import failed: ' + (msg || 'Please try a different file.'))[(fade ? "fadeIn" : "show")](); + $('#importmessagefail').html('Import failed: ' + (msg || 'Please copy paste'))[(fade ? "fadeIn" : "show")](); } if ($('#importexport .importmessage').is(':visible')) @@ -175,39 +177,6 @@ var padimpexp = (function() importDone(); } - function importApplicationSuccessful(data, textStatus) - { - if (data.substr(0, 2) == "ok") - { - if ($('#importexport .importmessage').is(':visible')) - { - $('#importexport .importmessage').hide(); - } - $('#importmessagesuccess').html('Import successful!').show(); - $('#importformfilediv').hide(); - window.setTimeout(function() - { - $('#importmessagesuccess').fadeOut("slow", function() - { - $('#importformfilediv').show(); - }); - if (hidePanelCall) - { - hidePanelCall(); - } - }, 3000); - } - else if (data.substr(0, 4) == "fail") - { - importErrorMessage("Couldn't update pad contents. This can happen if your web browser has \"cookies\" disabled."); - } - else if (data.substr(0, 4) == "msg:") - { - importErrorMessage(data.substr(4)); - } - importDone(); - } - ///// export function cantExport() @@ -290,16 +259,14 @@ var padimpexp = (function() $('#importform').submit(fileInputSubmit); $('.disabledexport').click(cantExport); }, - handleFrameCall: function(callName, argsArray) + handleFrameCall: function(status) { - if (callName == 'importFailed') + if (status !== "ok") { - importFailed(argsArray[0]); - } - else if (callName == 'importSuccessful') - { - importSuccessful(argsArray[0]); + importFailed(status); } + + importDone(); }, disable: function() { From 973aad5c96e5731ad6891f0d507b630d76c63c1b Mon Sep 17 00:00:00 2001 From: Peter 'Pita' Martischka Date: Mon, 27 Feb 2012 14:13:47 +0100 Subject: [PATCH 73/98] Fix doesPadExist check --- node/db/PadManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/db/PadManager.js b/node/db/PadManager.js index 126826123..4e3a31999 100644 --- a/node/db/PadManager.js +++ b/node/db/PadManager.js @@ -115,7 +115,7 @@ exports.doesPadExists = function(padId, callback) db.get("pad:"+padId, function(err, value) { if(ERR(err, callback)) return; - callback(null, value != null); + callback(null, value != null && value.atext); }); } From 0c770526982104d392284c4b1e2612794bf09e67 Mon Sep 17 00:00:00 2001 From: Peter 'Pita' Martischka Date: Mon, 27 Feb 2012 14:20:33 +0100 Subject: [PATCH 74/98] Fixed #299 and #338 --- node/handler/ImportHandler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/handler/ImportHandler.js b/node/handler/ImportHandler.js index 3dccb8af4..ed5eb05ee 100644 --- a/node/handler/ImportHandler.js +++ b/node/handler/ImportHandler.js @@ -82,7 +82,7 @@ exports.doImport = function(req, res, padId) //this allows us to accept source code files like .c or .java function(callback) { - var fileEnding = srcFile.split(".")[1].toLowerCase(); + var fileEnding = (srcFile.split(".")[1] || "").toLowerCase(); var knownFileEndings = ["txt", "doc", "docx", "pdf", "odt", "html", "htm"]; //find out if this is a known file ending From c54d47e1c6d141a3059939ff57d42b2b3ff985a6 Mon Sep 17 00:00:00 2001 From: Stefan 'Gared Date: Mon, 27 Feb 2012 15:24:36 +0000 Subject: [PATCH 75/98] Added cookie to save option showing author colors --- static/js/pad.js | 16 +++++++++++++++- static/js/pad_editor.js | 1 + static/pad.html | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/static/js/pad.js b/static/js/pad.js index d6bb4c717..426050987 100644 --- a/static/js/pad.js +++ b/static/js/pad.js @@ -282,7 +282,7 @@ function handshake() pad.changeViewOption('showLineNumbers', false); } - // If the noColors value is set to true then we need to hide the backround colors on the ace spans + // If the noColors value is set to true then we need to hide the background colors on the ace spans if (settings.noColors == true) { pad.changeViewOption('noColors', true); @@ -488,6 +488,9 @@ var pad = { chat.stickToScreen(true); // stick it to the screen $('#options-stickychat').prop("checked", true); // set the checkbox to on } + if(padcookie.getPref("showAuthorshipColors") == false){ + pad.changeViewOption('showAuthorColors', false); + } } }, dispose: function() @@ -752,6 +755,7 @@ var pad = { // pad.determineSidebarVisibility(isConnected && !isInitialConnect); pad.determineChatVisibility(isConnected && !isInitialConnect); + pad.determineAuthorshipColorsVisibility(); }, /* determineSidebarVisibility: function(asNowConnectedFeedback) @@ -781,6 +785,16 @@ var pad = { $('#options-stickychat').prop("checked", false); // set the checkbox for off } }, + determineAuthorshipColorsVisibility: function(){ + var authColCookie = padcookie.getPref('showAuthorshipColors'); + if (authColCookie){ + pad.changeViewOption('showAuthorColors', true); + $('#options-colorscheck').prop("checked", true); + } + else { + $('#options-colorscheck').prop("checked", false); + } + }, handleCollabAction: function(action) { if (action == "commitPerformed") diff --git a/static/js/pad_editor.js b/static/js/pad_editor.js index e838ae040..3dd67544d 100644 --- a/static/js/pad_editor.js +++ b/static/js/pad_editor.js @@ -69,6 +69,7 @@ var padeditor = (function() }); padutils.bindCheckboxChange($("#options-colorscheck"), function() { + padcookie.setPref('showAuthorshipColors', padutils.getCheckbox("#options-colorscheck")); pad.changeViewOption('showAuthorColors', padutils.getCheckbox("#options-colorscheck")); }); $("#viewfontmenu").change(function() diff --git a/static/pad.html b/static/pad.html index ea0ad6f3a..6f9665507 100644 --- a/static/pad.html +++ b/static/pad.html @@ -140,7 +140,7 @@

- +

From d00be5b8172af29e78e11b219b3a3ea5ef59611d Mon Sep 17 00:00:00 2001 From: Peter 'Pita' Martischka Date: Mon, 27 Feb 2012 17:33:27 +0100 Subject: [PATCH 76/98] Removed all window.unload event handlers. This kind of fixes #200 --- static/js/ace2_inner.js | 1 - static/js/collab_client.js | 7 ------- static/js/pad.js | 28 ++++++++++++++-------------- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/static/js/ace2_inner.js b/static/js/ace2_inner.js index 2418b3843..71f7d20f8 100644 --- a/static/js/ace2_inner.js +++ b/static/js/ace2_inner.js @@ -4654,7 +4654,6 @@ function Ace2Inner(){ function bindTheEventHandlers() { - bindEventHandler(window, "unload", teardown); bindEventHandler(document, "keydown", handleKeyEvent); bindEventHandler(document, "keypress", handleKeyEvent); bindEventHandler(document, "keyup", handleKeyEvent); diff --git a/static/js/collab_client.js b/static/js/collab_client.js index ec575fe0a..bb68f6040 100644 --- a/static/js/collab_client.js +++ b/static/js/collab_client.js @@ -84,13 +84,6 @@ function getCollabClient(ace2editor, serverVars, initialUserInfo, options, _pad) {} }; - $(window).bind("unload", function() - { - if (getSocket()) - { - setChannelState("DISCONNECTED", "unload"); - } - }); if ($.browser.mozilla) { // Prevent "escape" from taking effect and canceling a comet connection; diff --git a/static/js/pad.js b/static/js/pad.js index d6bb4c717..058213ce5 100644 --- a/static/js/pad.js +++ b/static/js/pad.js @@ -164,7 +164,8 @@ function handshake() //connect socket = pad.socket = io.connect(url, { resource: resource, - 'max reconnection attempts': 3 + 'max reconnection attempts': 3, + 'sync disconnect on unload' : false }); function sendClientReady(isReconnect) @@ -222,15 +223,19 @@ function handshake() sendClientReady(true); }); - socket.on('disconnect', function () { - function disconnectEvent() - { - pad.collabClient.setChannelState("DISCONNECTED", "reconnect_timeout"); + socket.on('disconnect', function (reason) { + if(reason == "booted"){ + pad.collabClient.setChannelState("DISCONNECTED"); + } else { + function disconnectEvent() + { + pad.collabClient.setChannelState("DISCONNECTED", "reconnect_timeout"); + } + + pad.collabClient.setChannelState("RECONNECTING"); + + disconnectTimeout = setTimeout(disconnectEvent, 10000); } - - pad.collabClient.setChannelState("RECONNECTING"); - - disconnectTimeout = setTimeout(disconnectEvent, 10000); }); var receivedClientVars = false; @@ -396,11 +401,6 @@ var pad = { getParams(); handshake(); }); - - $(window).unload(function() - { - pad.dispose(); - }); }, _afterHandshake: function() { From 5888f5ff7d0215d47c9622afef80497132922b3f Mon Sep 17 00:00:00 2001 From: Peter 'Pita' Martischka Date: Mon, 27 Feb 2012 19:13:25 +0100 Subject: [PATCH 77/98] @cweider, only Chuck Norris can compute in json files --- settings.json.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.json.template b/settings.json.template index 57bc5711b..94a60fd40 100644 --- a/settings.json.template +++ b/settings.json.template @@ -41,7 +41,7 @@ /* How long may clients use served javascript code? Without versioning this is may cause problems during deployment. */ - "maxAge" : 1000*60*60*6, // 6 hours + "maxAge" : 21600000, // 6 hours /* This is the path to the Abiword executable. Setting it to null, disables abiword. Abiword is needed to enable the import/export of pads*/ From 599c8c7c12870325f58e1b9ab6a916ed1473421f Mon Sep 17 00:00:00 2001 From: Peter 'Pita' Martischka Date: Mon, 27 Feb 2012 19:46:30 +0100 Subject: [PATCH 78/98] update dependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 35c3028a1..3231eb6ca 100644 --- a/package.json +++ b/package.json @@ -15,11 +15,11 @@ "require-kernel" : "1.0.3", "socket.io" : "0.8.7", "ueberDB" : "0.1.7", - "async" : "0.1.15", - "express" : "2.5.0", + "async" : "0.1.18", + "express" : "2.5.8", "clean-css" : "0.3.2", "uglify-js" : "1.2.5", - "formidable" : "1.0.7", + "formidable" : "1.0.9", "log4js" : "0.4.1", "jsdom-nocontextifiy" : "0.2.10", "async-stacktrace" : "0.0.2" From 5bfde917b074234755a46e55e534a7a70bd5e19f Mon Sep 17 00:00:00 2001 From: 0ip Date: Mon, 27 Feb 2012 22:04:03 +0100 Subject: [PATCH 79/98] revert viewport to fix #508 --- static/index.html | 2 +- static/pad.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/static/index.html b/static/index.html index da24a7a7c..8e0b02a97 100644 --- a/static/index.html +++ b/static/index.html @@ -4,7 +4,7 @@ Etherpad Lite - + + +

@@ -218,11 +188,9 @@
-
- - Chat -
-
+
+ Chat + 0
@@ -308,4 +276,4 @@ }()); - + \ No newline at end of file From b507f48a341517287eadffe066aa1b20ea761729 Mon Sep 17 00:00:00 2001 From: 0ip Date: Tue, 28 Feb 2012 21:37:10 +0100 Subject: [PATCH 85/98] typos --- static/css/pad.css | 1 - static/pad.html | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/static/css/pad.css b/static/css/pad.css index 2b6136656..fe188e474 100644 --- a/static/css/pad.css +++ b/static/css/pad.css @@ -813,7 +813,6 @@ ul#colorpickerswatches li:hover border: 1px solid #BBBBBB; width: 100%; float:right; - vertical-align: middle; } #chaticon diff --git a/static/pad.html b/static/pad.html index 30836f81c..4c6d4d8cf 100644 --- a/static/pad.html +++ b/static/pad.html @@ -53,13 +53,13 @@