Compare commits

...
Sign in to create a new pull request.

3 commits

Author SHA1 Message Date
Ubuntu
fdee7b9fa6 Removed mobile mode option 2012-12-02 22:06:07 +00:00
C9
81508772f3 Initial support for scrolling 2012-11-30 04:58:21 -05:00
C9
5c1aef3ccf First run test of iOS scrolling 2012-11-24 05:28:39 -05:00
6 changed files with 255 additions and 3 deletions

View file

@ -177,8 +177,6 @@ var keybindings = {
}) })
}; };
/*********** manage layout ***************************/ /*********** manage layout ***************************/
var consoleHeight = 20; var consoleHeight = 20;
function onResize() { function onResize() {
@ -395,6 +393,91 @@ bindCheckbox("highlight_token", function(checked) {
} }
}); });
bindCheckbox("mobile_mode", function(checked) {
/** Mobile test **/
if (checked) {
var editorElement = document.getElementById("editor");
var left = editorElement.offsetLeft;
var height = editorElement.style.height;
var totalHeight = env.editor.session.getLength() * env.editor.renderer.lineHeight;
var width = document.documentElement.clientWidth - left;
var mobileScrollDiv = document.createElement("div");
mobileScrollDiv.id = "scrolldiv_container";
mobileScrollDiv.style.width = (width+30) + "px";
//mobileScrollDiv.style.left = left + "px";
mobileScrollDiv.style.height = height;
var mobileScrollDivChild = document.createElement("div");
mobileScrollDivChild.id = "scrolldiv_child";
mobileScrollDivChild.style.height = totalHeight + "px";
mobileScrollDiv.appendChild(mobileScrollDivChild);
editorElement.appendChild(mobileScrollDiv);
var movementDiff = 0, lastMovementPos = 0;
var timeDiff = 0, lastTime = 0;
var waitingForLastScroll = false;
document.addEventListener("touchmove", function(e) {
//console.log(" TOUCHMOVE", e, mobileScrollDiv.scrollTop);
movementDiff = mobileScrollDiv.scrollTop - lastMovementPos;
lastMovementPos = mobileScrollDiv.scrollTop;
timeDiff = e.timeStamp - lastTime;
lastTime = e.timeStamp;
});
var movingTimer;
document.addEventListener("touchstart", function(e) {
if (e.target.className.split(" ").indexOf("ace_content") !== -1) {
clearInterval(movingTimer);
waitingForLastScroll = false;
movementDiff = 0, lastMovementPos = 0;
timeDiff = 0, lastTime = 0;
//console.log("touchstart", e);
}
}, false);
document.addEventListener("touchend", function(e) {
if (e.target.className.split(" ").indexOf("ace_content") !== -1) {
waitingForLastScroll = true;
//console.log("TOUCH END", e);
//console.log(movementDiff, timeDiff);
var position = mobileScrollDiv.scrollTop;
//var velocity = (movementDiff/timeDiff) * 4;
var velocity = movementDiff;
movingTimer = setInterval(function() {
position += velocity;
velocity *= 0.949;
//console.log(velocity);
env.editor.session.setScrollTop(position);
mobileScrollDiv.scrollTop = position;
if (Math.abs(velocity) < 4)
clearInterval(movingTimer);
}, 5);
}
}, false);
mobileScrollDiv.onscroll = function(e) {
//console.log("Scrolling", e, mobileScrollDiv.scrollTop);
if (waitingForLastScroll === false) {
env.editor.session.setScrollTop(mobileScrollDiv.scrollTop);
}
// Set the top of the scrolldiv to what the editor scrolltop is
/*else {
mobileScrollDiv.scrollTop = env.editor.session.getScrollTop();
}*/
};
}
else {
var mobileScrollDiv = document.getElementById("scrolldiv_container");
if (mobileScrollDiv)
mobileScrollDiv.parentNode.removeChild(mobileScrollDiv);
}
});
/************** dragover ***************************/ /************** dragover ***************************/
event.addListener(container, "dragover", function(e) { event.addListener(container, "dragover", function(e) {
return event.preventDefault(e); return event.preventDefault(e);

View file

@ -40,4 +40,19 @@ body {
#controls td + td { #controls td + td {
text-align: left; text-align: left;
}
#scrolldiv_container {
position: absolute;
top: 0px;
left: 0px;
z-index: 9999;
-webkit-overflow-scrolling: touch;
overflow-y: scroll;
pointer-events: none;
}
#scrolldiv_child {
-webkit-transform: translateZ(0px);
pointer-events: none;
} }

View file

@ -5,6 +5,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Ace Kitchen Sink</title> <title>Ace Kitchen Sink</title>
<meta name="author" content="Fabian Jakobs"> <meta name="author" content="Fabian Jakobs">
<meta name="viewport" content="user-scalable=no">
<!-- <!--
Ace Ace
version %version% version %version%
@ -27,7 +28,7 @@
<img id="logo" src="demo/kitchen-sink/logo.png"> <img id="logo" src="demo/kitchen-sink/logo.png">
</a> </a>
<div style="position: absolute; overflow: hidden; top:80px; bottom:0"> <div style="position: absolute; overflow: hidden; top:80px; bottom:0">
<div style="width: 120%; height:100%; overflow-y: scroll"> <div style="width: 120%; height:100%; overflow-y: scroll; -webkit-overflow-scrolling: touch">
<table id="controls"> <table id="controls">
<tr> <tr>

View file

@ -366,3 +366,19 @@
.ace_italic { .ace_italic {
font-style: italic; font-style: italic;
} }
.ace_mobile_scroll-layer {
-webkit-overflow-scrolling: touch;
overflow-y: scroll;
}
.ace_mobile_scroll-layer div {
z-index: 1;
position: absolute;
white-space: nowrap;
width: 100%;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
pointer-events: none;
}

View file

@ -0,0 +1,129 @@
/* ***** BEGIN LICENSE BLOCK *****
* Distributed under the BSD license:
*
* Copyright (c) 2010, Ajax.org B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Ajax.org B.V. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
"use strict";
var dom = require("../lib/dom");
var MobileScroll = function(parentEl) {
this.parentOverflowEl = dom.createElement("div");
this.parentOverflowEl.className = "ace_layer ace_mobile_scroll-layer";
this.element = dom.createElement("div");
this.parentOverflowEl.appendChild(this.element);
parentEl.appendChild(this.parentOverflowEl);
var _self = this;
var movementDiff = 0, lastMovementPos = 0;
var timeDiff = 0, lastTime = 0;
var waitingForLastScroll = false;
var stopInertialScrolling = false;
this.parentOverflowEl.onscroll = function(e) {
if (stopInertialScrolling) {
_self.parentOverflowEl.scrollTop = _self.session.getScrollTop();
return false;
}
if (_self.session)
_self.session.setScrollTop(_self.parentOverflowEl.scrollTop);
};
document.addEventListener("touchmove", function(e) {
movementDiff = _self.parentOverflowEl.scrollTop - lastMovementPos;
lastMovementPos = _self.parentOverflowEl.scrollTop;
timeDiff = e.timeStamp - lastTime;
lastTime = e.timeStamp;
});
var movingTimer;
var touchStartedWithAce = false;
document.addEventListener("touchstart", function(e) {
if (e.target.className.split(" ").indexOf("ace_content") === -1)
return true;
touchStartedWithAce = true;
stopInertialScrolling = false;
clearInterval(movingTimer);
waitingForLastScroll = false;
movementDiff = 0, lastMovementPos = 0;
timeDiff = 0, lastTime = 0;
}, false);
document.addEventListener("touchend", function(e) {
if (!touchStartedWithAce)
return true;
touchStartedWithAce = false;
waitingForLastScroll = true;
var position = _self.parentOverflowEl.scrollTop;
var velocity = movementDiff;
movingTimer = setInterval(function() {
position += velocity;
velocity *= 0.949;
_self.session.setScrollTop(position);
_self.parentOverflowEl.scrollTop = position;
if (Math.abs(velocity) < 4) {
clearInterval(movingTimer);
stopInertialScrolling = true;
}
}, 5);
}, false);
};
(function() {
this.setSession = function(session) {
this.session = session;
};
this.$padding = 0;
this.setPadding = function(padding) {
this.$padding = padding;
this.element.style.padding = "0 " + padding + "px";
};
this.setScrollTop = function(top) {
this.parentOverflowEl.scrollTop = top;
};
this.update = function(config) {
this.element.style.height = config.lineHeight * this.session.getScreenLength() + "px";
};
}).call(MobileScroll.prototype);
exports.MobileScroll = MobileScroll;
});

View file

@ -41,6 +41,7 @@ var GutterLayer = require("./layer/gutter").Gutter;
var MarkerLayer = require("./layer/marker").Marker; var MarkerLayer = require("./layer/marker").Marker;
var TextLayer = require("./layer/text").Text; var TextLayer = require("./layer/text").Text;
var CursorLayer = require("./layer/cursor").Cursor; var CursorLayer = require("./layer/cursor").Cursor;
var MobileScrollLayer = require("./layer/mobilescroll").MobileScroll;
var ScrollBar = require("./scrollbar").ScrollBar; var ScrollBar = require("./scrollbar").ScrollBar;
var RenderLoop = require("./renderloop").RenderLoop; var RenderLoop = require("./renderloop").RenderLoop;
var EventEmitter = require("./lib/event_emitter").EventEmitter; var EventEmitter = require("./lib/event_emitter").EventEmitter;
@ -104,6 +105,8 @@ var VirtualRenderer = function(container, theme) {
this.$markerFront = new MarkerLayer(this.content); this.$markerFront = new MarkerLayer(this.content);
this.$cursorLayer = new CursorLayer(this.content); this.$cursorLayer = new CursorLayer(this.content);
this.$mobileScrollLayer = new MobileScrollLayer(this.content);
// Indicates whether the horizontal scrollbar is visible // Indicates whether the horizontal scrollbar is visible
this.$horizScroll = false; this.$horizScroll = false;
@ -206,6 +209,7 @@ var VirtualRenderer = function(container, theme) {
this.scroller.className = "ace_scroller"; this.scroller.className = "ace_scroller";
this.$cursorLayer.setSession(session); this.$cursorLayer.setSession(session);
this.$mobileScrollLayer.setSession(session);
this.$markerBack.setSession(session); this.$markerBack.setSession(session);
this.$markerFront.setSession(session); this.$markerFront.setSession(session);
this.$gutterLayer.setSession(session); this.$gutterLayer.setSession(session);
@ -630,6 +634,7 @@ var VirtualRenderer = function(container, theme) {
this.setPadding = function(padding) { this.setPadding = function(padding) {
this.$padding = padding; this.$padding = padding;
this.$textLayer.setPadding(padding); this.$textLayer.setPadding(padding);
this.$mobileScrollLayer.setPadding(padding);
this.$cursorLayer.setPadding(padding); this.$cursorLayer.setPadding(padding);
this.$markerFront.setPadding(padding); this.$markerFront.setPadding(padding);
this.$markerBack.setPadding(padding); this.$markerBack.setPadding(padding);
@ -663,6 +668,7 @@ var VirtualRenderer = function(container, theme) {
this.$updateScrollBar = function() { this.$updateScrollBar = function() {
this.scrollBar.setInnerHeight(this.layerConfig.maxHeight); this.scrollBar.setInnerHeight(this.layerConfig.maxHeight);
this.scrollBar.setScrollTop(this.scrollTop); this.scrollBar.setScrollTop(this.scrollTop);
this.$mobileScrollLayer.setScrollTop(this.scrollTop);
}; };
this.$renderChanges = function(changes, force) { this.$renderChanges = function(changes, force) {
@ -695,6 +701,7 @@ var VirtualRenderer = function(container, theme) {
this.$textLayer.checkForSizeChanges(); this.$textLayer.checkForSizeChanges();
// update scrollbar first to not lose scroll position when gutter calls resize // update scrollbar first to not lose scroll position when gutter calls resize
this.$updateScrollBar(); this.$updateScrollBar();
this.$mobileScrollLayer.update(this.layerConfig);
this.$textLayer.update(this.layerConfig); this.$textLayer.update(this.layerConfig);
if (this.showGutter) if (this.showGutter)
this.$gutterLayer.update(this.layerConfig); this.$gutterLayer.update(this.layerConfig);
@ -726,6 +733,7 @@ var VirtualRenderer = function(container, theme) {
if (changes & this.CHANGE_TEXT) { if (changes & this.CHANGE_TEXT) {
this.$textLayer.update(this.layerConfig); this.$textLayer.update(this.layerConfig);
this.$mobileScrollLayer.update(this.layerConfig);
if (this.showGutter) if (this.showGutter)
this.$gutterLayer.update(this.layerConfig); this.$gutterLayer.update(this.layerConfig);
} }