-
Notifications
You must be signed in to change notification settings - Fork 14
/
mylib-pagetransition.js
189 lines (142 loc) · 5.81 KB
/
mylib-pagetransition.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
My Library Page Transition add-on
Requires DOM and Style modules
NOTE: At the moment the Transform add-on is also required as
the findProprietaryStyle function is created by it.
This function will be moved to the core in the near future.
*/
var API, global = this;
(function() {
var doc = global.document;
if (API && API.findProprietaryStyle && API.findProprietaryStyle('animation') && API.isHostMethod(doc, 'write') &&
API.isHostObjectProperty(doc, 'documentElement') && typeof doc.documentElement.style.visibility == 'string' && API.areFeatures && API.areFeatures('getEBI', 'getElementDocument', 'attachDocumentReadyListener')) {
// Global options and flag indicating first call of createPageTransition
var firstCall, deferTransition, contentContainerId, animationClassName;
// Writes transition-specific style sheet
// Most applications will call this once
// "Themed" applications call multiple times to write alternates
// Must be called from a script in the head of the document
API.createPageTransition = function(href, options, doc) {
if (!doc) {
doc = global.document;
}
if (!options) {
options = {};
}
// Only initial call can set global options
// Alternates can only specify name and max width
if (!firstCall) {
deferTransition = options.defer;
contentContainerId = options.contentContainerId;
animationClassName = options.className;
firstCall = true;
}
var link = '<link rel="stylesheet' + (options.alternate ? ' alternate' : '') + '" type="text/css" href="' + href.replace('&', '&') + '" media="screen and (' + 'max-' + (options.deviceWidth ? 'device-' : '') + 'width' + ': ' + (options.maxWidth || '480px') + ')"';
if (options.name) {
link += ' title="' + options.name + '"';
}
link += '">';
doc.write(link);
};
API.attachDocumentReadyListener(function() {
// Converts micro-format relationships to animation class names
var linkTransitions = {
home: 'up',
previous: 'forward',
next: 'back',
up: 'up',
down: 'down'
};
API.addPageTransitionClassName = function(rel, className) {
linkTransitions[rel] = className;
};
var getElementDocument = API.getElementDocument, getEBI = API.getEBI;
var testHash = /\#.*$/;
var testFullyQualified = /^[^:]*:\/{1,3}[^\/]*(\/.*)$/;
var testMail = /^mailto:/;
var testNews = /^news:/;
API.transitionPage = function(contentContainer, className) {
var body, dir, doc, find, head, href, i, link, links, matches, referrer;
// If no class name specified, set to previously provided
if (!className) {
className = animationClassName;
}
// If no previously provided class name, try to determine direction
// from links in head and content container
if (!className) {
// Determine content container and document
if (contentContainer) {
doc = getElementDocument(contentContainer);
} else {
if (contentContainerId) {
contentContainer = getEBI(contentContainerId);
if (contentContainer) {
doc = getElementDocument(contentContainer);
}
}
if (!contentContainer) {
doc = contentContainer = global.document;
}
}
body = API.getBodyElement(doc);
referrer = doc.referrer;
// Loops through links looking for referrer match
find = function(referrer, defaultDir) {
var done;
for (i = links.length; i-- && !done;) {
href = links[i].href;
if (href && !testFullyQualified.test(href) && !testMail.test(href) && !testNews.test(href)) {
done = true;
matches = referrer.match(testFullyQualified);
if (matches) {
referrer = matches[1];
}
}
}
for (i = links.length; i-- && !dir;) {
link = links[i];
href = link.href.replace(testHash, '');
if (href == referrer && (defaultDir || linkTransitions[link.rel])) {
dir = link.rel || defaultDir;
}
}
};
// No referrer results in no transition
if (referrer) {
// Strip fragment identifier
referrer = referrer.replace(testHash, '');
// Check links in head first
head = doc.getElementsByTagName('head')[0];
links = head.getElementsByTagName('link');
find(referrer);
// If no match found, search content container
if (!dir) {
links = contentContainer.getElementsByTagName('a');
// Default direction is up for links in content container
// as most will be lacking rel attribute and can be assumed to
// be down the path
find(referrer, 'up');
}
// Set the animation class name if direction determined
if (dir) {
className = linkTransitions[dir];
}
}
}
if (className) {
var bodyClassName = body.className;
body.className = bodyClassName ? bodyClassName + ' ' + className : className;
// Put body class back after a second so that the transition
// will not repeat itself on resizes that cross the width threshold
global.setTimeout(function() {
body.className = bodyClassName;
}, 1000);
}
body.style.visibility = 'visible';
};
if (!deferTransition) {
API.transitionPage();
}
});
}
})();