2012-11-03 12:34:36 +00:00
|
|
|
/*\
|
|
|
|
title: $:/core/modules/macros/scrollable.js
|
|
|
|
type: application/javascript
|
|
|
|
module-type: macro
|
|
|
|
|
|
|
|
Creates a scrollable frame around its content
|
|
|
|
|
|
|
|
\*/
|
|
|
|
(function(){
|
|
|
|
|
|
|
|
/*jslint node: true, browser: true */
|
|
|
|
/*global $tw: false */
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
exports.info = {
|
|
|
|
name: "scrollable",
|
|
|
|
params: {
|
|
|
|
width: {byName: true, type: "text"},
|
|
|
|
height: {byName: true, type: "text"},
|
|
|
|
"class": {byName: true, type: "text"}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.executeMacro = function() {
|
|
|
|
var innerClasses = ["tw-scrollable-inner"],
|
|
|
|
innerAttributes = {
|
|
|
|
"class": innerClasses,
|
|
|
|
style: {
|
|
|
|
overflow: "visible",
|
|
|
|
position: "relative"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
outerClasses = ["tw-scrollable","tw-scrollable-outer"],
|
|
|
|
outerAttributes = {
|
|
|
|
"class": outerClasses,
|
|
|
|
style: {
|
2012-11-03 17:35:31 +00:00
|
|
|
overflow: "auto",
|
2012-11-03 17:36:27 +00:00
|
|
|
"-webkit-overflow-scrolling": "touch",
|
2012-11-03 12:34:36 +00:00
|
|
|
"white-space": "nowrap"
|
|
|
|
}
|
|
|
|
};
|
|
|
|
if(this.hasParameter("class")) {
|
|
|
|
outerClasses.push(this.params["class"]);
|
|
|
|
}
|
|
|
|
if(this.classes) {
|
|
|
|
$tw.utils.pushTop(outerClasses,this.classes);
|
|
|
|
}
|
|
|
|
if(this.hasParameter("width")) {
|
2012-11-06 17:21:56 +00:00
|
|
|
outerAttributes.style.width = this.params.width;
|
2012-11-03 12:34:36 +00:00
|
|
|
}
|
|
|
|
if(this.hasParameter("height")) {
|
2012-11-06 17:21:56 +00:00
|
|
|
outerAttributes.style.height = this.params.height;
|
2012-11-03 12:34:36 +00:00
|
|
|
}
|
|
|
|
var innerFrame = $tw.Tree.Element("div",innerAttributes,this.content),
|
|
|
|
outerFrame = $tw.Tree.Element("div",outerAttributes,[innerFrame]);
|
|
|
|
outerFrame.execute(this.parents,this.tiddlerTitle);
|
|
|
|
return outerFrame;
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.postRenderInDom = function() {
|
2012-11-03 16:14:00 +00:00
|
|
|
// Attach a scrollTo() method to the outer wrapper
|
|
|
|
var self = this;
|
|
|
|
this.child.children[0].domNode.scrollTo = function(bounds) {
|
|
|
|
self.scrollTo.call(self,bounds);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
var slowInSlowOut = function(t) {
|
|
|
|
return (1 - ((Math.cos(t * Math.PI) + 1) / 2));
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.scrollTo = function(bounds) {
|
|
|
|
this.cancelScroll();
|
|
|
|
this.startTime = new Date();
|
|
|
|
this.startX = this.child.domNode.scrollLeft;
|
|
|
|
this.startY = this.child.domNode.scrollTop;
|
|
|
|
this.endX = bounds.left;
|
|
|
|
this.endY = bounds.top;
|
|
|
|
if((this.endX < this.startX) || (this.endX > (this.startX + this.child.domNode.offsetWidth)) || (this.endY < this.startY) || (this.endY > (this.startY + this.child.domNode.offsetHeight))) {
|
|
|
|
var self = this;
|
|
|
|
this.scrollTimerId = window.setInterval(function() {
|
|
|
|
var t = ((new Date()) - self.startTime) / $tw.config.preferences.animationDuration;
|
|
|
|
if(t >= 1) {
|
|
|
|
self.cancelScroll();
|
|
|
|
t = 1;
|
|
|
|
}
|
|
|
|
t = slowInSlowOut(t);
|
2012-11-06 17:21:56 +00:00
|
|
|
self.child.domNode.scrollLeft = self.startX + (self.endX - self.startX) * t;
|
2012-11-03 16:14:00 +00:00
|
|
|
self.child.domNode.scrollTop = self.startY + (self.endY - self.startY) * t;
|
|
|
|
}, 10);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.cancelScroll = function() {
|
|
|
|
if(this.scrollTimerId) {
|
|
|
|
window.clearInterval(this.scrollTimerId);
|
|
|
|
this.scrollTimerId = null;
|
|
|
|
}
|
2012-11-03 12:34:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
})();
|