diff options
author | Grant Gayed <grant_gayed@ca.ibm.com> | 2014-05-14 17:12:07 -0400 |
---|---|---|
committer | Grant Gayed <grant_gayed@ca.ibm.com> | 2014-05-14 17:12:32 -0400 |
commit | bafc1b6e30095a794234cedc8b0aae605a2e15d1 (patch) | |
tree | bdf308115bbca7bd1f70ddf06da4d176f840b20c | |
parent | 911c38f27ed8429e957e5b7d419a2747918b5905 (diff) | |
download | org.eclipse.orion.client-origin/stable_20140514.zip org.eclipse.orion.client-origin/stable_20140514.tar.gz org.eclipse.orion.client-origin/stable_20140514.tar.bz2 |
scroll markdown preview pane in response to source editor scrollsorigin/stable_20140514
4 files changed, 129 insertions, 93 deletions
diff --git a/bundles/org.eclipse.orion.client.editor/web/orion/editor/textStyler.js b/bundles/org.eclipse.orion.client.editor/web/orion/editor/textStyler.js index b6d7f57..5b03fe5 100644 --- a/bundles/org.eclipse.orion.client.editor/web/orion/editor/textStyler.js +++ b/bundles/org.eclipse.orion.client.editor/web/orion/editor/textStyler.js @@ -793,10 +793,6 @@ define("orion/editor/textStyler", ['orion/editor/annotations', 'orion/editor/eve getBlocks: function() { return this._subBlocks; }, -// getPatterns: function() { -// /* all patterns appear in the line patterns list */ -// return this.getLinePatterns(); -// }, isRenderingWhitespace: function() { return this.styler._isRenderingWhitespace(); } @@ -806,9 +802,6 @@ define("orion/editor/textStyler", ['orion/editor/annotations', 'orion/editor/eve this._styler = styler; } TextStylerAccessor.prototype = { -// getPatterns: function(offset) { -// return this._styler.getPatterns(offset); -// }, getStyles: function(offset) { return this._styler.getStyles(offset); } @@ -887,6 +880,9 @@ define("orion/editor/textStyler", ['orion/editor/annotations', 'orion/editor/eve this._view = null; } }, + getBlockAtIndex: function(index) { + return this._findBlock(this._rootBlock, index); + }, getRootBlock: function() { return this._rootBlock; }, diff --git a/bundles/org.eclipse.orion.client.editor/web/orion/editor/textView.js b/bundles/org.eclipse.orion.client.editor/web/orion/editor/textView.js index 46f37d7..ee2141b 100644 --- a/bundles/org.eclipse.orion.client.editor/web/orion/editor/textView.js +++ b/bundles/org.eclipse.orion.client.editor/web/orion/editor/textView.js @@ -251,71 +251,7 @@ define("orion/editor/textView", [ //$NON-NLS-0$ head.insertBefore(style, head.firstChild); } - /** - * @class - * @private - * @name orion.editor.Animation - * @description Creates an animation. - * @param {Object} options Options controlling the animation. - * @param {Array} options.curve Array of 2 values giving the start and end points for the animation. - * @param {Number} [options.duration=350] Duration of the animation, in milliseconds. - * @param {Function} [options.easing] - * @param {Function} [options.onAnimate] - * @param {Function} [options.onEnd] - * @param {Number} [options.rate=20] The time between frames, in milliseconds. - */ - var Animation = /** @ignore */ (function() { - function Animation(options) { - this.options = options; - } - /** - * Plays this animation. - * @function - * @memberOf orion.editor.Animation.prototype - * @name play - */ - Animation.prototype.play = function() { - var duration = (typeof this.options.duration === "number") ? this.options.duration : 350, //$NON-NLS-0$ - rate = (typeof this.options.rate === "number") ? this.options.rate : 20, //$NON-NLS-0$ - easing = this.options.easing || this.defaultEasing, - onAnimate = this.options.onAnimate || function() {}, - start = this.options.curve[0], - end = this.options.curve[1], - range = (end - start), - startedAt = -1, - propertyValue, - self = this; - - function onFrame() { - startedAt = (startedAt === -1) ? new Date().getTime() : startedAt; - var now = new Date().getTime(), - percentDone = (now - startedAt) / duration; - if (percentDone < 1) { - var eased = easing(percentDone); - propertyValue = start + (eased * range); - onAnimate(propertyValue); - } else { - onAnimate(end); - self.stop(); - } - } - this.interval = this.options.window.setInterval(onFrame, rate); - }; - /** - * Stops this animation. - * @function - * @memberOf orion.editor.Animation.prototype - */ - Animation.prototype.stop = function() { - this.options.window.clearInterval(this.interval); - var onEnd = this.options.onEnd || function () {}; - onEnd(); - }; - Animation.prototype.defaultEasing = function(x) { - return Math.sin(x * (Math.PI / 2)); - }; - return Animation; - }()); + var Animation = textUtil.Animation; /** * Constructs a new Selection object. diff --git a/bundles/org.eclipse.orion.client.editor/web/orion/editor/util.js b/bundles/org.eclipse.orion.client.editor/web/orion/editor/util.js index e94daee..3138f3e 100644 --- a/bundles/org.eclipse.orion.client.editor/web/orion/editor/util.js +++ b/bundles/org.eclipse.orion.client.editor/web/orion/editor/util.js @@ -45,9 +45,76 @@ define("orion/editor/util", [], function() { //$NON-NLS-0$ return topNode === node || (topNode.compareDocumentPosition(node) & 16) !== 0;
}
+ /**
+ * @class
+ * @private
+ * @name orion.editor.Animation
+ * @description Creates an animation.
+ * @param {Object} options Options controlling the animation.
+ * @param {Array} options.curve Array of 2 values giving the start and end points for the animation.
+ * @param {Number} [options.duration=350] Duration of the animation, in milliseconds.
+ * @param {Function} [options.easing]
+ * @param {Function} [options.onAnimate]
+ * @param {Function} [options.onEnd]
+ * @param {Number} [options.rate=20] The time between frames, in milliseconds.
+ */
+ var Animation = /** @ignore */ (function() {
+ function Animation(options) {
+ this.options = options;
+ }
+ /**
+ * Plays this animation.
+ * @function
+ * @memberOf orion.editor.Animation.prototype
+ * @name play
+ */
+ Animation.prototype.play = function() {
+ var duration = (typeof this.options.duration === "number") ? this.options.duration : 350, //$NON-NLS-0$
+ rate = (typeof this.options.rate === "number") ? this.options.rate : 20, //$NON-NLS-0$
+ easing = this.options.easing || this.defaultEasing,
+ onAnimate = this.options.onAnimate || function() {},
+ start = this.options.curve[0],
+ end = this.options.curve[1],
+ range = (end - start),
+ startedAt = -1,
+ propertyValue,
+ self = this;
+
+ function onFrame() {
+ startedAt = (startedAt === -1) ? new Date().getTime() : startedAt;
+ var now = new Date().getTime(),
+ percentDone = (now - startedAt) / duration;
+ if (percentDone < 1) {
+ var eased = easing(percentDone);
+ propertyValue = start + (eased * range);
+ onAnimate(propertyValue);
+ } else {
+ onAnimate(end);
+ self.stop();
+ }
+ }
+ this.interval = this.options.window.setInterval(onFrame, rate);
+ };
+ /**
+ * Stops this animation.
+ * @function
+ * @memberOf orion.editor.Animation.prototype
+ */
+ Animation.prototype.stop = function() {
+ this.options.window.clearInterval(this.interval);
+ var onEnd = this.options.onEnd || function () {};
+ onEnd();
+ };
+ Animation.prototype.defaultEasing = function(x) {
+ return Math.sin(x * (Math.PI / 2));
+ };
+ return Animation;
+ }());
+
return {
contains: contains,
addEventListener: addEventListener,
- removeEventListener: removeEventListener
+ removeEventListener: removeEventListener,
+ Animation: Animation
};
});
\ No newline at end of file diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/markdownEditor.js b/bundles/org.eclipse.orion.client.ui/web/orion/markdownEditor.js index 586ee27..313702d 100644 --- a/bundles/org.eclipse.orion.client.ui/web/orion/markdownEditor.js +++ b/bundles/org.eclipse.orion.client.ui/web/orion/markdownEditor.js @@ -13,12 +13,13 @@ define([ 'marked/marked', 'orion/editor/editor', 'orion/editor/textStyler', + 'orion/editor/util', 'orion/objects', 'orion/webui/littlelib', 'orion/URITemplate', 'orion/webui/splitter', 'orion/URL-shim' -], function(marked, mEditor, mTextStyler, objects, lib, URITemplate, mSplitter) { +], function(marked, mEditor, mTextStyler, mTextUtil, objects, lib, URITemplate, mSplitter) { var uriTemplate = new URITemplate("#{,resource,params*}"); //$NON-NLS-0$ var extensionRegex = /\.([0-9a-z]+)(?:[\?#]|$)/i; @@ -268,7 +269,7 @@ define([ return null; }, initialPopulatePreview: function() { - /* hack, see the explaination in MarkdownEditor.createStyler() */ + /* hack, see the explaination in MarkdownEditor.initSourceEditor() */ var rootBlock = this._styler.getRootBlock(); this._onBlocksChanged({old: [], new: rootBlock.getBlocks()}); }, @@ -514,18 +515,57 @@ define([ this._parent = options.parent; this._model = options.model; this._editorView = options.editorView; + + this._scrollListener = function(/*e*/) { + var textView = this._editorView.editor.getTextView(); + var charIndex = textView.getOffsetAtLocation(0, (textView.getBottomPixel() + textView.getTopPixel()) / 2); + var block = this._styler.getBlockAtIndex(charIndex); + if (block) { + var element = document.getElementById(block.elementId); + if (element) { + if (this._animation) { + this._animation.stop(); + this._animation = null; + } + + var newTop = Math.max(0, Math.floor(element.offsetTop - (this._previewDiv.clientHeight - element.offsetHeight) / 2)); + var pixelY = newTop - this._previewDiv.scrollTop; + if (!pixelY) { + return; + } + + this._animation = new mTextUtil.Animation({ + window: window, + curve: [pixelY, 0], + onAnimate: function(x) { + var deltaY = pixelY - Math.floor(x); + this._previewDiv.scrollTop += deltaY; + pixelY -= deltaY; + }.bind(this), + onEnd: function() { + this._animation = null; + this._previewDiv.scrollTop += pixelY; + }.bind(this) + }); + this._animation.play(); + } + } + }.bind(this); + BaseEditor.apply(this, arguments); } MarkdownEditor.prototype = Object.create(BaseEditor.prototype); objects.mixin(MarkdownEditor.prototype, /** @lends orion.edit.MarkdownEditor.prototype */ { - createStyler: function() { + initSourceEditor: function() { var editor = this._editorView.editor; var textView = editor.getTextView(); var annotationModel = editor.getAnnotationModel(); var stylerAdapter = new MarkdownStylingAdapter(this._model, this._metadata.Location, this._fileService); this._styler = new mTextStyler.TextStyler(textView, annotationModel, stylerAdapter); + this._editorView.editor.getTextView().addEventListener("Scroll", this._scrollListener); + /* * If the model already has content then it is being shared with a previous * editor that was open on the same resource. In this case this editor's @@ -560,26 +600,27 @@ define([ splitterDiv.id = "orion.markdown.editor.splitter"; rootDiv.appendChild(splitterDiv); - var previewDiv = document.createElement("div"); //$NON-NLS-0$ - previewDiv.className = "mainPanelLayout hasSplit"; //$NON-NLS-0$ - previewDiv.id = ID_PREVIEW; //$NON-NLS-0$ - previewDiv.style.position = "absolute"; //$NON-NLS-0$ - previewDiv.style.height = "100%"; //$NON-NLS-0$ - previewDiv.style.overflowX = "hidden"; //$NON-NLS-0$ - previewDiv.style.overflowY = "auto"; //$NON-NLS-0$ - previewDiv.classList.add("orionMarkdown"); //$NON-NLS-0$ - rootDiv.appendChild(previewDiv); + this._previewDiv = document.createElement("div"); //$NON-NLS-0$ + this._previewDiv.className = "mainPanelLayout hasSplit"; //$NON-NLS-0$ + this._previewDiv.id = ID_PREVIEW; //$NON-NLS-0$ + this._previewDiv.style.position = "absolute"; //$NON-NLS-0$ + this._previewDiv.style.height = "100%"; //$NON-NLS-0$ + this._previewDiv.style.overflowX = "hidden"; //$NON-NLS-0$ + this._previewDiv.style.overflowY = "auto"; //$NON-NLS-0$ + this._previewDiv.classList.add("orionMarkdown"); //$NON-NLS-0$ + rootDiv.appendChild(this._previewDiv); new mSplitter.Splitter({ node: splitterDiv, sidePanel: editorDiv, - mainPanel: previewDiv + mainPanel: this._previewDiv }); BaseEditor.prototype.install.call(this); }, uninstall: function() { this._styler.destroy(); + this._editorView.editor.getTextView().removeEventListener("Scroll", this._scrollListener); lib.empty(this._parent); BaseEditor.prototype.uninstall.call(this); } @@ -593,16 +634,12 @@ define([ this.editor = new MarkdownEditor(this._options); this.editor.install(); this._options.editorView.create(); - this.editor.createStyler(); + this.editor.initSourceEditor(); }, destroy: function() { - if (this.editor) { - this.editor.destroy(); - } + this.editor.destroy(); this.editor = null; - if (this._options.editorView) { - this._options.editorView.destroy(); - } + this._options.editorView.destroy(); this._options.editorView = null; } }; |