Compare commits
3 commits
master
...
feature/io
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fdee7b9fa6 | ||
|
|
81508772f3 | ||
|
|
5c1aef3ccf |
6 changed files with 255 additions and 3 deletions
|
|
@ -177,8 +177,6 @@ var keybindings = {
|
|||
})
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*********** manage layout ***************************/
|
||||
var consoleHeight = 20;
|
||||
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 ***************************/
|
||||
event.addListener(container, "dragover", function(e) {
|
||||
return event.preventDefault(e);
|
||||
|
|
|
|||
|
|
@ -40,4 +40,19 @@ body {
|
|||
|
||||
#controls td + td {
|
||||
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;
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Ace Kitchen Sink</title>
|
||||
<meta name="author" content="Fabian Jakobs">
|
||||
<meta name="viewport" content="user-scalable=no">
|
||||
<!--
|
||||
Ace
|
||||
version %version%
|
||||
|
|
@ -27,7 +28,7 @@
|
|||
<img id="logo" src="demo/kitchen-sink/logo.png">
|
||||
</a>
|
||||
<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">
|
||||
<tr>
|
||||
|
|
|
|||
|
|
@ -366,3 +366,19 @@
|
|||
.ace_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;
|
||||
}
|
||||
129
lib/ace/layer/mobilescroll.js
Normal file
129
lib/ace/layer/mobilescroll.js
Normal 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;
|
||||
|
||||
});
|
||||
|
|
@ -41,6 +41,7 @@ var GutterLayer = require("./layer/gutter").Gutter;
|
|||
var MarkerLayer = require("./layer/marker").Marker;
|
||||
var TextLayer = require("./layer/text").Text;
|
||||
var CursorLayer = require("./layer/cursor").Cursor;
|
||||
var MobileScrollLayer = require("./layer/mobilescroll").MobileScroll;
|
||||
var ScrollBar = require("./scrollbar").ScrollBar;
|
||||
var RenderLoop = require("./renderloop").RenderLoop;
|
||||
var EventEmitter = require("./lib/event_emitter").EventEmitter;
|
||||
|
|
@ -104,6 +105,8 @@ var VirtualRenderer = function(container, theme) {
|
|||
this.$markerFront = new MarkerLayer(this.content);
|
||||
|
||||
this.$cursorLayer = new CursorLayer(this.content);
|
||||
|
||||
this.$mobileScrollLayer = new MobileScrollLayer(this.content);
|
||||
|
||||
// Indicates whether the horizontal scrollbar is visible
|
||||
this.$horizScroll = false;
|
||||
|
|
@ -206,6 +209,7 @@ var VirtualRenderer = function(container, theme) {
|
|||
this.scroller.className = "ace_scroller";
|
||||
|
||||
this.$cursorLayer.setSession(session);
|
||||
this.$mobileScrollLayer.setSession(session);
|
||||
this.$markerBack.setSession(session);
|
||||
this.$markerFront.setSession(session);
|
||||
this.$gutterLayer.setSession(session);
|
||||
|
|
@ -630,6 +634,7 @@ var VirtualRenderer = function(container, theme) {
|
|||
this.setPadding = function(padding) {
|
||||
this.$padding = padding;
|
||||
this.$textLayer.setPadding(padding);
|
||||
this.$mobileScrollLayer.setPadding(padding);
|
||||
this.$cursorLayer.setPadding(padding);
|
||||
this.$markerFront.setPadding(padding);
|
||||
this.$markerBack.setPadding(padding);
|
||||
|
|
@ -663,6 +668,7 @@ var VirtualRenderer = function(container, theme) {
|
|||
this.$updateScrollBar = function() {
|
||||
this.scrollBar.setInnerHeight(this.layerConfig.maxHeight);
|
||||
this.scrollBar.setScrollTop(this.scrollTop);
|
||||
this.$mobileScrollLayer.setScrollTop(this.scrollTop);
|
||||
};
|
||||
|
||||
this.$renderChanges = function(changes, force) {
|
||||
|
|
@ -695,6 +701,7 @@ var VirtualRenderer = function(container, theme) {
|
|||
this.$textLayer.checkForSizeChanges();
|
||||
// update scrollbar first to not lose scroll position when gutter calls resize
|
||||
this.$updateScrollBar();
|
||||
this.$mobileScrollLayer.update(this.layerConfig);
|
||||
this.$textLayer.update(this.layerConfig);
|
||||
if (this.showGutter)
|
||||
this.$gutterLayer.update(this.layerConfig);
|
||||
|
|
@ -726,6 +733,7 @@ var VirtualRenderer = function(container, theme) {
|
|||
|
||||
if (changes & this.CHANGE_TEXT) {
|
||||
this.$textLayer.update(this.layerConfig);
|
||||
this.$mobileScrollLayer.update(this.layerConfig);
|
||||
if (this.showGutter)
|
||||
this.$gutterLayer.update(this.layerConfig);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue