monocle-rails 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.DS_Store +0 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/lib/monocle/rails.rb +8 -0
- data/lib/monocle/rails/version.rb +5 -0
- data/monocle-rails.gemspec +23 -0
- data/vendor/.DS_Store +0 -0
- data/vendor/assets/.DS_Store +0 -0
- data/vendor/assets/javascripts/.DS_Store +0 -0
- data/vendor/assets/javascripts/compat/browser.js +120 -0
- data/vendor/assets/javascripts/compat/css.js +145 -0
- data/vendor/assets/javascripts/compat/env.js +463 -0
- data/vendor/assets/javascripts/compat/gala.js +469 -0
- data/vendor/assets/javascripts/compat/stubs.js +50 -0
- data/vendor/assets/javascripts/controls/contents.js +59 -0
- data/vendor/assets/javascripts/controls/magnifier.js +51 -0
- data/vendor/assets/javascripts/controls/panel.js +136 -0
- data/vendor/assets/javascripts/controls/placesaver.js +100 -0
- data/vendor/assets/javascripts/controls/scrubber.js +140 -0
- data/vendor/assets/javascripts/controls/spinner.js +99 -0
- data/vendor/assets/javascripts/controls/stencil.js +410 -0
- data/vendor/assets/javascripts/core/billboard.js +120 -0
- data/vendor/assets/javascripts/core/book.js +467 -0
- data/vendor/assets/javascripts/core/bookdata.js +59 -0
- data/vendor/assets/javascripts/core/component.js +413 -0
- data/vendor/assets/javascripts/core/events.js +56 -0
- data/vendor/assets/javascripts/core/factory.js +194 -0
- data/vendor/assets/javascripts/core/formatting.js +317 -0
- data/vendor/assets/javascripts/core/monocle.js +16 -0
- data/vendor/assets/javascripts/core/place.js +210 -0
- data/vendor/assets/javascripts/core/reader.js +683 -0
- data/vendor/assets/javascripts/core/selection.js +158 -0
- data/vendor/assets/javascripts/core/styles.js +155 -0
- data/vendor/assets/javascripts/dimensions/columns.js +218 -0
- data/vendor/assets/javascripts/flippers/instant.js +78 -0
- data/vendor/assets/javascripts/flippers/scroller.js +128 -0
- data/vendor/assets/javascripts/flippers/slider.js +469 -0
- data/vendor/assets/javascripts/monocore.js +27 -0
- data/vendor/assets/javascripts/monoctrl.js +1 -0
- data/vendor/assets/javascripts/panels/eink.js +61 -0
- data/vendor/assets/javascripts/panels/imode.js +180 -0
- data/vendor/assets/javascripts/panels/magic.js +297 -0
- data/vendor/assets/javascripts/panels/marginal.js +50 -0
- data/vendor/assets/javascripts/panels/twopane.js +34 -0
- data/vendor/assets/stylesheets/monocore.css +194 -0
- data/vendor/assets/stylesheets/monoctrl.css +168 -0
- metadata +129 -0
@@ -0,0 +1,158 @@
|
|
1
|
+
Monocle.Selection = function (reader) {
|
2
|
+
var API = { constructor: Monocle.Selection };
|
3
|
+
var k = API.constants = API.constructor;
|
4
|
+
var p = API.properties = {
|
5
|
+
reader: reader,
|
6
|
+
lastSelection: []
|
7
|
+
};
|
8
|
+
|
9
|
+
|
10
|
+
function initialize() {
|
11
|
+
if (k.SELECTION_POLLING_INTERVAL) {
|
12
|
+
setInterval(pollSelection, k.SELECTION_POLLING_INTERVAL);
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
|
17
|
+
function pollSelection() {
|
18
|
+
var index = 0, frame = null;
|
19
|
+
while (frame = reader.dom.find('component', index++)) {
|
20
|
+
if (frame.contentWindow) {
|
21
|
+
pollSelectionOnWindow(frame.contentWindow, index);
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
|
27
|
+
function pollSelectionOnWindow(win, index) {
|
28
|
+
var sel = win.getSelection();
|
29
|
+
if (!sel) { return; }
|
30
|
+
var lm = p.lastSelection[index] || {};
|
31
|
+
var nm = p.lastSelection[index] = {
|
32
|
+
selected: anythingSelected(win),
|
33
|
+
range: sel.rangeCount ? sel.getRangeAt(0) : null,
|
34
|
+
string: sel.toString()
|
35
|
+
};
|
36
|
+
if (nm.selected) {
|
37
|
+
nm.rangeStartContainer = nm.range.startContainer;
|
38
|
+
nm.rangeEndContainer = nm.range.endContainer;
|
39
|
+
nm.rangeStartOffset = nm.range.startOffset;
|
40
|
+
nm.rangeEndOffset = nm.range.endOffset;
|
41
|
+
if (!sameRange(nm, lm)) {
|
42
|
+
p.reader.dispatchEvent('monocle:selection', nm);
|
43
|
+
}
|
44
|
+
} else if (lm.selected) {
|
45
|
+
p.reader.dispatchEvent('monocle:deselection', lm);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
|
50
|
+
function sameRange(m1, m2) {
|
51
|
+
return (
|
52
|
+
m1.rangeStartContainer == m2.rangeStartContainer &&
|
53
|
+
m1.rangeEndContainer == m2.rangeEndContainer &&
|
54
|
+
m1.rangeStartOffset == m2.rangeStartOffset &&
|
55
|
+
m1.rangeEndOffset == m2.rangeEndOffset
|
56
|
+
);
|
57
|
+
}
|
58
|
+
|
59
|
+
|
60
|
+
// Given a window object, remove any user selections within. Trivial in
|
61
|
+
// most browsers, but involving major mojo on iOS.
|
62
|
+
//
|
63
|
+
function deselect() {
|
64
|
+
var index = 0, frame = null;
|
65
|
+
while (frame = reader.dom.find('component', index++)) {
|
66
|
+
deselectOnWindow(frame.contentWindow);
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
|
71
|
+
function deselectOnWindow(win) {
|
72
|
+
win = win || window;
|
73
|
+
if (!anythingSelected(win)) { return; }
|
74
|
+
|
75
|
+
if (Monocle.Browser.iOSVersion && !Monocle.Browser.iOSVersionBelow(5)) {
|
76
|
+
preservingScale(function () {
|
77
|
+
preservingScrollPosition(function () {
|
78
|
+
var inp = document.createElement('input');
|
79
|
+
inp.style.cssText = [
|
80
|
+
'position: absolute',
|
81
|
+
'top: 0',
|
82
|
+
'left: 0',
|
83
|
+
'width: 0',
|
84
|
+
'height: 0'
|
85
|
+
].join(';');
|
86
|
+
document.body.appendChild(inp);
|
87
|
+
inp.focus();
|
88
|
+
document.body.removeChild(inp);
|
89
|
+
})
|
90
|
+
});
|
91
|
+
}
|
92
|
+
|
93
|
+
var sel = win.getSelection();
|
94
|
+
sel.removeAllRanges();
|
95
|
+
win.document.body.scrollLeft = 0;
|
96
|
+
win.document.body.scrollTop = 0;
|
97
|
+
}
|
98
|
+
|
99
|
+
|
100
|
+
function preservingScrollPosition(fn) {
|
101
|
+
var sx = window.scrollX, sy = window.scrollY;
|
102
|
+
fn();
|
103
|
+
window.scrollTo(sx, sy);
|
104
|
+
}
|
105
|
+
|
106
|
+
|
107
|
+
function preservingScale(fn) {
|
108
|
+
var head = document.querySelector('head');
|
109
|
+
var ovp = head.querySelector('meta[name=viewport]');
|
110
|
+
var createViewportMeta = function (content) {
|
111
|
+
var elem = document.createElement('meta');
|
112
|
+
elem.setAttribute('name', 'viewport');
|
113
|
+
elem.setAttribute('content', content);
|
114
|
+
head.appendChild(elem);
|
115
|
+
return elem;
|
116
|
+
}
|
117
|
+
|
118
|
+
var nvp;
|
119
|
+
if (ovp) {
|
120
|
+
var ovpcontent = ovp.getAttribute('content');
|
121
|
+
var re = /user-scalable\s*=\s*([^,$\s])*/;
|
122
|
+
var result = ovpcontent.match(re);
|
123
|
+
if (result && ['no', '0'].indexOf(result[1]) >= 0) {
|
124
|
+
fn();
|
125
|
+
} else {
|
126
|
+
var nvpcontent = ovpcontent.replace(re, '');
|
127
|
+
nvpcontent += nvpcontent ? ', ' : '';
|
128
|
+
nvpcontent += 'user-scalable=no';
|
129
|
+
head.removeChild(ovp);
|
130
|
+
nvp = createViewportMeta(nvpcontent);
|
131
|
+
fn();
|
132
|
+
head.removeChild(nvp);
|
133
|
+
head.appendChild(ovp);
|
134
|
+
}
|
135
|
+
} else {
|
136
|
+
nvp = createViewportMeta('user-scalable=no');
|
137
|
+
fn();
|
138
|
+
nvp.setAttribute('content', 'user-scalable=yes');
|
139
|
+
}
|
140
|
+
}
|
141
|
+
|
142
|
+
|
143
|
+
function anythingSelected(win) {
|
144
|
+
var sel = win.getSelection();
|
145
|
+
return sel && !sel.isCollapsed;
|
146
|
+
}
|
147
|
+
|
148
|
+
|
149
|
+
API.deselect = deselect;
|
150
|
+
|
151
|
+
|
152
|
+
initialize();
|
153
|
+
|
154
|
+
return API;
|
155
|
+
}
|
156
|
+
|
157
|
+
|
158
|
+
Monocle.Selection.SELECTION_POLLING_INTERVAL = 250;
|
@@ -0,0 +1,155 @@
|
|
1
|
+
Monocle.Styles = {
|
2
|
+
|
3
|
+
// Takes a hash and returns a string.
|
4
|
+
rulesToString: function (rules) {
|
5
|
+
if (typeof rules != 'string') {
|
6
|
+
var parts = [];
|
7
|
+
for (var declaration in rules) {
|
8
|
+
parts.push(declaration+": "+rules[declaration]+";")
|
9
|
+
}
|
10
|
+
rules = parts.join(" ");
|
11
|
+
}
|
12
|
+
return rules;
|
13
|
+
},
|
14
|
+
|
15
|
+
|
16
|
+
// Takes a hash or string of CSS property assignments and applies them
|
17
|
+
// to the element.
|
18
|
+
//
|
19
|
+
applyRules: function (elem, rules) {
|
20
|
+
rules = Monocle.Styles.rulesToString(rules);
|
21
|
+
elem.style.cssText += ';'+rules;
|
22
|
+
return elem.style.cssText;
|
23
|
+
},
|
24
|
+
|
25
|
+
|
26
|
+
// Generates cross-browser properties for a given property.
|
27
|
+
// ie, affix(<elem>, 'transition', 'linear 100ms') would apply that value
|
28
|
+
// to webkitTransition for WebKit browsers, and to MozTransition for Gecko.
|
29
|
+
//
|
30
|
+
affix: function (elem, property, value) {
|
31
|
+
var target = elem.style ? elem.style : elem;
|
32
|
+
var props = Monocle.Browser.css.toDOMProps(property);
|
33
|
+
while (props.length) { target[props.shift()] = value; }
|
34
|
+
},
|
35
|
+
|
36
|
+
|
37
|
+
setX: function (elem, x) {
|
38
|
+
var s = elem.style;
|
39
|
+
if (typeof x == "number") { x += "px"; }
|
40
|
+
var val = Monocle.Browser.env.supportsTransform3d ?
|
41
|
+
'translate3d('+x+', 0, 0)' :
|
42
|
+
'translateX('+x+')';
|
43
|
+
val = (x == '0px') ? 'none' : val;
|
44
|
+
s.webkitTransform = s.MozTransform = s.OTransform = s.transform = val;
|
45
|
+
return x;
|
46
|
+
},
|
47
|
+
|
48
|
+
|
49
|
+
setY: function (elem, y) {
|
50
|
+
var s = elem.style;
|
51
|
+
if (typeof y == "number") { y += "px"; }
|
52
|
+
var val = Monocle.Browser.env.supportsTransform3d ?
|
53
|
+
'translate3d(0, '+y+', 0)' :
|
54
|
+
'translateY('+y+')';
|
55
|
+
val = (y == '0px') ? 'none' : val;
|
56
|
+
s.webkitTransform = s.MozTransform = s.OTransform = s.transform = val;
|
57
|
+
return y;
|
58
|
+
},
|
59
|
+
|
60
|
+
|
61
|
+
getX: function (elem) {
|
62
|
+
var currStyle = document.defaultView.getComputedStyle(elem, null);
|
63
|
+
var re = /matrix\([^,]+,[^,]+,[^,]+,[^,]+,\s*([^,]+),[^\)]+\)/;
|
64
|
+
var props = Monocle.Browser.css.toDOMProps('transform');
|
65
|
+
var matrix = null;
|
66
|
+
while (props.length && !matrix) {
|
67
|
+
matrix = currStyle[props.shift()];
|
68
|
+
}
|
69
|
+
return parseInt(matrix.match(re)[1], 10);
|
70
|
+
},
|
71
|
+
|
72
|
+
|
73
|
+
transitionFor: function (elem, prop, duration, timing, delay) {
|
74
|
+
var tProps = Monocle.Browser.css.toDOMProps('transition');
|
75
|
+
var pProps = Monocle.Browser.css.toCSSProps(prop);
|
76
|
+
timing = timing || "linear";
|
77
|
+
delay = (delay || 0)+"ms";
|
78
|
+
for (var i = 0, ii = tProps.length; i < ii; ++i) {
|
79
|
+
var t = "none";
|
80
|
+
if (duration) {
|
81
|
+
t = [pProps[i], duration+"ms", timing, delay].join(" ");
|
82
|
+
}
|
83
|
+
elem.style[tProps[i]] = t;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
}
|
88
|
+
|
89
|
+
|
90
|
+
// These rule definitions are more or less compulsory for Monocle to behave
|
91
|
+
// as expected. Which is why they appear here and not in the stylesheet.
|
92
|
+
// Adjust them if you know what you're doing.
|
93
|
+
//
|
94
|
+
Monocle.Styles.container = {
|
95
|
+
"position": "absolute",
|
96
|
+
"overflow": "hidden",
|
97
|
+
"top": "0",
|
98
|
+
"left": "0",
|
99
|
+
"bottom": "0",
|
100
|
+
"right": "0"
|
101
|
+
}
|
102
|
+
|
103
|
+
Monocle.Styles.page = {
|
104
|
+
"position": "absolute",
|
105
|
+
"z-index": "1",
|
106
|
+
"-webkit-user-select": "none",
|
107
|
+
"-moz-user-select": "none",
|
108
|
+
"-ms-user-select": "none",
|
109
|
+
"user-select": "none",
|
110
|
+
"-webkit-transform": "translate3d(0,0,0)",
|
111
|
+
"visibility": "visible"
|
112
|
+
|
113
|
+
/*
|
114
|
+
"background": "white",
|
115
|
+
"top": "0",
|
116
|
+
"left": "0",
|
117
|
+
"bottom": "0",
|
118
|
+
"right": "0"
|
119
|
+
*/
|
120
|
+
}
|
121
|
+
|
122
|
+
Monocle.Styles.sheaf = {
|
123
|
+
"position": "absolute",
|
124
|
+
"overflow": "hidden"
|
125
|
+
|
126
|
+
/*
|
127
|
+
"top": "0",
|
128
|
+
"left": "0",
|
129
|
+
"bottom": "0",
|
130
|
+
"right": "0"
|
131
|
+
*/
|
132
|
+
}
|
133
|
+
|
134
|
+
Monocle.Styles.component = {
|
135
|
+
"width": "100%",
|
136
|
+
"height": "100%",
|
137
|
+
"border": "none",
|
138
|
+
"-webkit-user-select": "none",
|
139
|
+
"-moz-user-select": "none",
|
140
|
+
"-ms-user-select": "none",
|
141
|
+
"user-select": "none"
|
142
|
+
}
|
143
|
+
|
144
|
+
Monocle.Styles.control = {
|
145
|
+
"z-index": "100",
|
146
|
+
"cursor": "pointer"
|
147
|
+
}
|
148
|
+
|
149
|
+
Monocle.Styles.overlay = {
|
150
|
+
"position": "absolute",
|
151
|
+
"display": "none",
|
152
|
+
"width": "100%",
|
153
|
+
"height": "100%",
|
154
|
+
"z-index": "1000"
|
155
|
+
}
|
@@ -0,0 +1,218 @@
|
|
1
|
+
Monocle.Dimensions.Columns = function (pageDiv) {
|
2
|
+
|
3
|
+
var API = { constructor: Monocle.Dimensions.Columns }
|
4
|
+
var k = API.constants = API.constructor;
|
5
|
+
var p = API.properties = {
|
6
|
+
page: pageDiv,
|
7
|
+
reader: pageDiv.m.reader,
|
8
|
+
length: 0,
|
9
|
+
width: 0
|
10
|
+
}
|
11
|
+
|
12
|
+
// Logically, forceColumn browsers can't have a gap, because that would
|
13
|
+
// make the minWidth > 200%. But how much greater? Not worth the effort.
|
14
|
+
k.GAP = Monocle.Browser.env.forceColumns ? 0 : 20;
|
15
|
+
|
16
|
+
function update(callback) {
|
17
|
+
setColumnWidth();
|
18
|
+
Monocle.defer(function () {
|
19
|
+
p.length = columnCount();
|
20
|
+
if (Monocle.DEBUG) {
|
21
|
+
console.log(
|
22
|
+
'page['+p.page.m.pageIndex+'] -> '+p.length+
|
23
|
+
' ('+p.page.m.activeFrame.m.component.properties.id+')'
|
24
|
+
);
|
25
|
+
}
|
26
|
+
callback(p.length);
|
27
|
+
});
|
28
|
+
}
|
29
|
+
|
30
|
+
|
31
|
+
function setColumnWidth() {
|
32
|
+
var pdims = pageDimensions();
|
33
|
+
var ce = columnedElement();
|
34
|
+
|
35
|
+
p.width = pdims.width;
|
36
|
+
|
37
|
+
var rules = Monocle.Styles.rulesToString(k.STYLE["columned"]);
|
38
|
+
rules += Monocle.Browser.css.toCSSDeclaration('column-width', pdims.col+'px');
|
39
|
+
rules += Monocle.Browser.css.toCSSDeclaration('column-gap', k.GAP+'px');
|
40
|
+
rules += Monocle.Browser.css.toCSSDeclaration('column-fill', 'auto');
|
41
|
+
rules += Monocle.Browser.css.toCSSDeclaration('transform', 'none');
|
42
|
+
|
43
|
+
if (Monocle.Browser.env.forceColumns && ce.scrollHeight > pdims.height) {
|
44
|
+
rules += Monocle.Styles.rulesToString(k.STYLE['column-force']);
|
45
|
+
if (Monocle.DEBUG) {
|
46
|
+
console.warn("Force columns ("+ce.scrollHeight+" > "+pdims.height+")");
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
if (ce.style.cssText != rules) {
|
51
|
+
// Update offset because we're translating to zero.
|
52
|
+
p.page.m.offset = 0;
|
53
|
+
|
54
|
+
// IE10 hack.
|
55
|
+
if (Monocle.Browser.env.documentElementHasScrollbars) {
|
56
|
+
ce.ownerDocument.documentElement.style.overflow = 'hidden';
|
57
|
+
}
|
58
|
+
|
59
|
+
// Apply body style changes.
|
60
|
+
ce.style.cssText = rules;
|
61
|
+
|
62
|
+
if (Monocle.Browser.env.scrollToApplyStyle) {
|
63
|
+
ce.scrollLeft = 0;
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
|
69
|
+
// Returns the element to which columns CSS should be applied.
|
70
|
+
//
|
71
|
+
function columnedElement() {
|
72
|
+
return p.page.m.activeFrame.contentDocument.body;
|
73
|
+
}
|
74
|
+
|
75
|
+
|
76
|
+
// Returns the width of the offsettable area of the columned element. By
|
77
|
+
// definition, the number of pages is always this divided by the
|
78
|
+
// width of a single page (eg, the client area of the columned element).
|
79
|
+
//
|
80
|
+
function columnedWidth() {
|
81
|
+
var bd = columnedElement();
|
82
|
+
var de = p.page.m.activeFrame.contentDocument.documentElement;
|
83
|
+
|
84
|
+
var w = Math.max(bd.scrollWidth, de.scrollWidth);
|
85
|
+
|
86
|
+
// Add one because the final column doesn't have right gutter.
|
87
|
+
// w += k.GAP;
|
88
|
+
|
89
|
+
if (!Monocle.Browser.env.widthsIgnoreTranslate && p.page.m.offset) {
|
90
|
+
w += p.page.m.offset;
|
91
|
+
}
|
92
|
+
return w;
|
93
|
+
}
|
94
|
+
|
95
|
+
|
96
|
+
function pageDimensions() {
|
97
|
+
var elem = p.page.m.sheafDiv;
|
98
|
+
var w = elem.clientWidth;
|
99
|
+
if (elem.getBoundingClientRect) { w = elem.getBoundingClientRect().width; }
|
100
|
+
if (Monocle.Browser.env.roundPageDimensions) { w = Math.round(w); }
|
101
|
+
return { col: w, width: w + k.GAP, height: elem.clientHeight }
|
102
|
+
}
|
103
|
+
|
104
|
+
|
105
|
+
function columnCount() {
|
106
|
+
return Math.ceil(columnedWidth() / pageDimensions().width)
|
107
|
+
}
|
108
|
+
|
109
|
+
|
110
|
+
function locusToOffset(locus) {
|
111
|
+
return pageDimensions().width * (locus.page - 1);
|
112
|
+
}
|
113
|
+
|
114
|
+
|
115
|
+
// Moves the columned element to the offset implied by the locus.
|
116
|
+
//
|
117
|
+
// The 'transition' argument is optional, allowing the translation to be
|
118
|
+
// animated. If not given, no change is made to the columned element's
|
119
|
+
// transition property.
|
120
|
+
//
|
121
|
+
function translateToLocus(locus, transition) {
|
122
|
+
var offset = locusToOffset(locus);
|
123
|
+
p.page.m.offset = offset;
|
124
|
+
translateToOffset(offset, transition);
|
125
|
+
return offset;
|
126
|
+
}
|
127
|
+
|
128
|
+
|
129
|
+
function translateToOffset(offset, transition) {
|
130
|
+
var ce = columnedElement();
|
131
|
+
if (transition) {
|
132
|
+
Monocle.Styles.affix(ce, "transition", transition);
|
133
|
+
}
|
134
|
+
// NB: can't use setX as it causes a flicker on iOS.
|
135
|
+
Monocle.Styles.affix(ce, "transform", "translateX(-"+offset+"px)");
|
136
|
+
}
|
137
|
+
|
138
|
+
|
139
|
+
function percentageThroughOfNode(target) {
|
140
|
+
if (!target) { return 0; }
|
141
|
+
var doc = p.page.m.activeFrame.contentDocument;
|
142
|
+
var offset = 0;
|
143
|
+
if (Monocle.Browser.env.findNodesByScrolling) {
|
144
|
+
// First, remove translation...
|
145
|
+
translateToOffset(0);
|
146
|
+
|
147
|
+
// Store scroll offsets for all windows.
|
148
|
+
var win, s;
|
149
|
+
win = s = p.page.m.activeFrame.contentWindow;
|
150
|
+
var scrollers = [
|
151
|
+
[win, win.scrollX, win.scrollY],
|
152
|
+
[window, window.scrollX, window.scrollY]
|
153
|
+
];
|
154
|
+
//while (s != s.parent) { scrollers.push([s, s.scrollX]); s = s.parent; }
|
155
|
+
|
156
|
+
var scroller, x;
|
157
|
+
if (Monocle.Browser.env.sheafIsScroller) {
|
158
|
+
scroller = p.page.m.sheafDiv;
|
159
|
+
x = scroller.scrollLeft;
|
160
|
+
target.scrollIntoView();
|
161
|
+
offset = scroller.scrollLeft;
|
162
|
+
} else {
|
163
|
+
scroller = win;
|
164
|
+
x = scroller.scrollX;
|
165
|
+
target.scrollIntoView();
|
166
|
+
offset = scroller.scrollX;
|
167
|
+
}
|
168
|
+
|
169
|
+
// Restore scroll offsets for all windows.
|
170
|
+
while (s = scrollers.shift()) {
|
171
|
+
s[0].scrollTo(s[1], s[2]);
|
172
|
+
}
|
173
|
+
|
174
|
+
// ... finally, replace translation.
|
175
|
+
translateToOffset(p.page.m.offset);
|
176
|
+
} else {
|
177
|
+
offset = target.getBoundingClientRect().left;
|
178
|
+
offset -= doc.body.getBoundingClientRect().left;
|
179
|
+
}
|
180
|
+
|
181
|
+
// We know at least 1px will be visible, and offset should not be 0.
|
182
|
+
offset += 1;
|
183
|
+
|
184
|
+
// Percent is the offset divided by the total width of the component.
|
185
|
+
var percent = offset / (p.length * p.width);
|
186
|
+
|
187
|
+
// Page number would be offset divided by the width of a single page.
|
188
|
+
// var pageNum = Math.ceil(offset / pageDimensions().width);
|
189
|
+
|
190
|
+
return percent;
|
191
|
+
}
|
192
|
+
|
193
|
+
|
194
|
+
API.update = update;
|
195
|
+
API.percentageThroughOfNode = percentageThroughOfNode;
|
196
|
+
|
197
|
+
API.locusToOffset = locusToOffset;
|
198
|
+
API.translateToLocus = translateToLocus;
|
199
|
+
|
200
|
+
return API;
|
201
|
+
}
|
202
|
+
|
203
|
+
|
204
|
+
Monocle.Dimensions.Columns.STYLE = {
|
205
|
+
// Most of these are already applied to body, but they're repeated here
|
206
|
+
// in case columnedElement() is ever anything other than body.
|
207
|
+
"columned": {
|
208
|
+
"margin": "0",
|
209
|
+
"padding": "0",
|
210
|
+
"height": "100%",
|
211
|
+
"width": "100%",
|
212
|
+
"position": "absolute"
|
213
|
+
},
|
214
|
+
"column-force": {
|
215
|
+
"min-width": "200%",
|
216
|
+
"overflow": "hidden"
|
217
|
+
}
|
218
|
+
}
|