├── .gitignore
├── Gruntfile.js
├── LICENSE
├── README.md
├── _config.yml
├── layout
├── _partial
│ ├── after-footer.ejs
│ ├── archive-post.ejs
│ ├── archive.ejs
│ ├── article.ejs
│ ├── footer.ejs
│ ├── google-analytics.ejs
│ ├── head.ejs
│ ├── mobile-nav.ejs
│ ├── post
│ │ ├── category.ejs
│ │ ├── date.ejs
│ │ ├── nav.ejs
│ │ └── title.ejs
│ └── sidebar.ejs
├── archive.ejs
├── category.ejs
├── index.ejs
├── layout.ejs
├── page.ejs
├── post.ejs
└── tag.ejs
├── package.json
├── scripts
└── fancybox.js
└── source
├── css
├── _extend.styl
├── _partial
│ ├── archive.styl
│ ├── article.styl
│ ├── comment.styl
│ ├── footer.styl
│ ├── highlight.styl
│ ├── mobile.styl
│ └── sidebar.styl
├── _util
│ ├── grid.styl
│ └── mixin.styl
├── _variables.styl
├── fonts
│ ├── iconfont.eot
│ ├── iconfont.svg
│ ├── iconfont.ttf
│ └── iconfont.woff
├── gist.styl
└── style.styl
├── fancybox
├── blank.gif
├── fancybox_loading.gif
├── fancybox_loading@2x.gif
├── fancybox_overlay.png
├── fancybox_sprite.png
├── fancybox_sprite@2x.png
├── helpers
│ ├── fancybox_buttons.png
│ ├── jquery.fancybox-buttons.css
│ ├── jquery.fancybox-buttons.js
│ ├── jquery.fancybox-media.js
│ ├── jquery.fancybox-thumbs.css
│ └── jquery.fancybox-thumbs.js
├── jquery.fancybox.css
├── jquery.fancybox.js
└── jquery.fancybox.pack.js
└── js
└── script.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
18 | .grunt
19 |
20 | # node-waf configuration
21 | .lock-wscript
22 |
23 | # Compiled binary addons (http://nodejs.org/api/addons.html)
24 | build/Release
25 |
26 | # Dependency directory
27 | node_modules
28 |
29 | # Optional npm cache directory
30 | .npm
31 |
32 | # Optional REPL history
33 | .node_repl_history
34 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt){
2 | grunt.initConfig({
3 | gitclone: {
4 | fontawesome: {
5 | options: {
6 | repository: 'https://github.com/FortAwesome/Font-Awesome.git',
7 | directory: 'tmp/fontawesome'
8 | },
9 | },
10 | fancybox: {
11 | options: {
12 | repository: 'https://github.com/fancyapps/fancyBox.git',
13 | directory: 'tmp/fancybox'
14 | }
15 | }
16 | },
17 | copy: {
18 | fontawesome: {
19 | expand: true,
20 | cwd: 'tmp/fontawesome/fonts/',
21 | src: ['**'],
22 | dest: 'source/css/fonts/'
23 | },
24 | fancybox: {
25 | expand: true,
26 | cwd: 'tmp/fancybox/source/',
27 | src: ['**'],
28 | dest: 'source/fancybox/'
29 | }
30 | },
31 | _clean: {
32 | tmp: ['tmp'],
33 | fontawesome: ['source/css/fonts'],
34 | fancybox: ['source/fancybox']
35 | }
36 | });
37 |
38 | require('load-grunt-tasks')(grunt);
39 |
40 | grunt.renameTask('clean', '_clean');
41 |
42 | grunt.registerTask('fontawesome', ['gitclone:fontawesome', 'copy:fontawesome', '_clean:tmp']);
43 | grunt.registerTask('fancybox', ['gitclone:fancybox', 'copy:fancybox', '_clean:tmp']);
44 | grunt.registerTask('default', ['gitclone', 'copy', '_clean:tmp']);
45 | grunt.registerTask('clean', ['_clean']);
46 | };
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Hejx
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # hexo-theme-jane
2 |
3 | ### 关于
4 |
5 | 这是一个极其简单的 hexo 主题,甚至说,她是不及格的。这完全是按照我自己的需求和想法来设计的一个主题,没有太多的功能,例如,没有搜索功能,没有海贼王和火影忍者,没有分享,也没有脸书和推特。因为,我只希望这仅仅是一个给自己记录文字的地方,所以,没有太多花俏的功能!
6 |
7 | 如果您也喜欢这样,欢迎您使用的我的主题!
8 |
9 | ### 安装
10 |
11 | ```bash
12 | git clone https://github.com/hejianxian/hexo-theme-jane.git themes/jane
13 | ```
14 |
15 | 然后配置根目录的_config.yml文件(并非theme里的那个)
16 |
17 | ```bash
18 | theme: jane
19 | ```
20 |
21 | 若要作为git子模块安装
22 | ```bash
23 | git submodule add https://github.com/hejianxian/hexo-theme-jane.git themes/jane
24 | ```
25 | [关于git子模块](https://yuguo.us/weblog/git-submodule/)
26 |
27 | ### 关于评论
28 |
29 | 新的 jane 主题使用了 [gitment](https://github.com/imsun/gitment) 评论系统,具体操作请看[这里](https://imsun.net/posts/gitment-introduction/),若有任何问题,欢迎提 issue。
30 |
31 | 如果注册 OAuth App 成功后,需要修改主题文件,找到`layout/_partial/article.ejs`,拉到最底下:
32 |
33 | ```js
34 | // 请在这里正确地设置信息
35 | var gitment = new Gitment({
36 | owner: '你的 github account',
37 | repo: '接收 issue 的仓库,这里只需要仓库名字',
38 | oauth: {
39 | client_id: '创建 oauth 成功后的 client_id',
40 | client_secret: '创建 oauth 成功后的 client_secret',
41 | },
42 | })
43 | gitment.render('comments')
44 | ```
45 |
46 | 编辑后,重新编译并发布即可看到效果。
47 |
48 | ### tags
49 | 因为tags是单独一个页面展示,所以需要手动添加,输入以下命令就可以了
50 |
51 | ```bash
52 | hexo new page tags
53 | ```
54 |
55 | ### 更新
56 |
57 | ```bash
58 | cd themes/jane
59 | git pull
60 | ```
61 |
62 | ### License
63 |
64 | MIT
65 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | # Header
2 | menu:
3 | Home: /
4 | Archives: /archives
5 | Tag: /tags
6 | Github: https://github.com/hejianxian
7 | rss: /atom.xml
8 |
9 | # Content
10 | excerpt_link: More...
11 | fancybox: true
12 |
13 | # Miscellaneous
14 | google_analytics:
15 | favicon: /favicon.png
16 |
--------------------------------------------------------------------------------
/layout/_partial/after-footer.ejs:
--------------------------------------------------------------------------------
1 | <% if (config.disqus_shortname){ %>
2 |
15 | <% } %>
16 |
17 |
18 |
19 | <% if (theme.fancybox){ %>
20 | <%- css('fancybox/jquery.fancybox') %>
21 | <%- js('fancybox/jquery.fancybox.pack') %>
22 | <% } %>
23 |
24 | <%- js('js/script') %>
25 |
--------------------------------------------------------------------------------
/layout/_partial/archive-post.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%- partial('post/date', {class_name: 'archive-article-date', date_format: 'MMM D'}) %>
5 | <%- partial('post/title', {class_name: 'archive-article-title'}) %>
6 |
7 |
8 |
--------------------------------------------------------------------------------
/layout/_partial/archive.ejs:
--------------------------------------------------------------------------------
1 | <% if (pagination == 2){ %>
2 | <% page.posts.each(function(post){ %>
3 | <%- partial('article', {post: post, index: true}) %>
4 | <% }) %>
5 | <% if (page.total > 1){ %>
6 |
12 | <% } %>
13 | <% } else { %>
14 | <% var last; %>
15 | <%
16 | var posts = site.posts
17 | if (page.tag) {
18 | posts = site.posts.filter(function(post) {
19 | return post.tags.data.map(function(item) { return item.name }).some(function(tag) {
20 | return tag === page.tag
21 | })
22 | })
23 | }
24 | %>
25 | <% posts.sort('date', -1).each(function(post, i){ %>
26 | <% var year = post.date.year(); %>
27 | <% if (last != year){ %>
28 | <% if (last != null){ %>
29 |
30 | <% } %>
31 | <% last = year; %>
32 |
33 |
36 |
37 | <% } %>
38 | <%- partial('archive-post', {post: post, even: i % 2 == 0}) %>
39 | <% }) %>
40 | <% if (site.posts.length){ %>
41 |
42 | <% } %>
43 | <% } %>
--------------------------------------------------------------------------------
/layout/_partial/article.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <% if (post.link || post.title){ %>
5 |
6 | <%- partial('post/title', {class_name: 'article-title'}) %>
7 |
8 | <% } %>
9 |
10 | <%- partial('post/date', {class_name: 'article-date', date_format: null}) %>
11 | <%- partial('post/category') %>
12 |
13 |
14 | <% if (post.excerpt && index){ %>
15 | <%- post.excerpt %>
16 | <% if (theme.excerpt_link){ %>
17 |
18 | <%= theme.excerpt_link %>
19 |
20 | <% } %>
21 | <% } else { %>
22 | <%- post.content %>
23 | <% } %>
24 |
25 | <% if (page.path === "tags/index.html"){ %>
26 | <%- list_tags() %>
27 | <% } %>
28 |
29 |
30 |
31 | <% if (!index){ %>
32 | <%- partial('post/nav') %>
33 | <% } %>
34 |
35 |
36 | <% if (!index && post.comments && config.disqus_shortname && page.path !== "tags/index.html"){ %>
37 |
52 | <% } %>
53 |
--------------------------------------------------------------------------------
/layout/_partial/footer.ejs:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/layout/_partial/google-analytics.ejs:
--------------------------------------------------------------------------------
1 | <% if (theme.google_analytics){ %>
2 |
3 |
13 |
14 | <% } %>
15 |
--------------------------------------------------------------------------------
/layout/_partial/head.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
3 | <%- list_categories(post.categories, {
4 | show_count: false,
5 | class: 'article-category',
6 | style: 'none',
7 | separator: ' '
8 | }) %>
9 |
10 | <% } %>
--------------------------------------------------------------------------------
/layout/_partial/post/date.ejs:
--------------------------------------------------------------------------------
1 | The requested content cannot be loaded.
Please try again later.
',
144 | closeBtn : '').html(content).find(current.selector);
1107 |
1108 | } else if (isQuery(content)) {
1109 | if (!content.data(placeholder)) {
1110 | content.data(placeholder, $('
').insertAfter( content ).hide() );
1111 | }
1112 |
1113 | content = content.show().detach();
1114 |
1115 | current.wrap.bind('onReset', function () {
1116 | if ($(this).find(content).length) {
1117 | content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false);
1118 | }
1119 | });
1120 | }
1121 | break;
1122 |
1123 | case 'image':
1124 | content = current.tpl.image.replace(/\{href\}/g, href);
1125 | break;
1126 |
1127 | case 'swf':
1128 | content = '
';
1137 | break;
1138 | }
1139 |
1140 | if (!(isQuery(content) && content.parent().is(current.inner))) {
1141 | current.inner.append( content );
1142 | }
1143 |
1144 | // Give a chance for helpers or callbacks to update elements
1145 | F.trigger('beforeShow');
1146 |
1147 | // Set scrolling before calculating dimensions
1148 | current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling));
1149 |
1150 | // Set initial dimensions and start position
1151 | F._setDimension();
1152 |
1153 | F.reposition();
1154 |
1155 | F.isOpen = false;
1156 | F.coming = null;
1157 |
1158 | F.bindEvents();
1159 |
1160 | if (!F.isOpened) {
1161 | $('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove();
1162 |
1163 | } else if (previous.prevMethod) {
1164 | F.transitions[ previous.prevMethod ]();
1165 | }
1166 |
1167 | F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ]();
1168 |
1169 | F._preloadImages();
1170 | },
1171 |
1172 | _setDimension: function () {
1173 | var viewport = F.getViewport(),
1174 | steps = 0,
1175 | canShrink = false,
1176 | canExpand = false,
1177 | wrap = F.wrap,
1178 | skin = F.skin,
1179 | inner = F.inner,
1180 | current = F.current,
1181 | width = current.width,
1182 | height = current.height,
1183 | minWidth = current.minWidth,
1184 | minHeight = current.minHeight,
1185 | maxWidth = current.maxWidth,
1186 | maxHeight = current.maxHeight,
1187 | scrolling = current.scrolling,
1188 | scrollOut = current.scrollOutside ? current.scrollbarWidth : 0,
1189 | margin = current.margin,
1190 | wMargin = getScalar(margin[1] + margin[3]),
1191 | hMargin = getScalar(margin[0] + margin[2]),
1192 | wPadding,
1193 | hPadding,
1194 | wSpace,
1195 | hSpace,
1196 | origWidth,
1197 | origHeight,
1198 | origMaxWidth,
1199 | origMaxHeight,
1200 | ratio,
1201 | width_,
1202 | height_,
1203 | maxWidth_,
1204 | maxHeight_,
1205 | iframe,
1206 | body;
1207 |
1208 | // Reset dimensions so we could re-check actual size
1209 | wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp');
1210 |
1211 | wPadding = getScalar(skin.outerWidth(true) - skin.width());
1212 | hPadding = getScalar(skin.outerHeight(true) - skin.height());
1213 |
1214 | // Any space between content and viewport (margin, padding, border, title)
1215 | wSpace = wMargin + wPadding;
1216 | hSpace = hMargin + hPadding;
1217 |
1218 | origWidth = isPercentage(width) ? (viewport.w - wSpace) * getScalar(width) / 100 : width;
1219 | origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height;
1220 |
1221 | if (current.type === 'iframe') {
1222 | iframe = current.content;
1223 |
1224 | if (current.autoHeight && iframe.data('ready') === 1) {
1225 | try {
1226 | if (iframe[0].contentWindow.document.location) {
1227 | inner.width( origWidth ).height(9999);
1228 |
1229 | body = iframe.contents().find('body');
1230 |
1231 | if (scrollOut) {
1232 | body.css('overflow-x', 'hidden');
1233 | }
1234 |
1235 | origHeight = body.outerHeight(true);
1236 | }
1237 |
1238 | } catch (e) {}
1239 | }
1240 |
1241 | } else if (current.autoWidth || current.autoHeight) {
1242 | inner.addClass( 'fancybox-tmp' );
1243 |
1244 | // Set width or height in case we need to calculate only one dimension
1245 | if (!current.autoWidth) {
1246 | inner.width( origWidth );
1247 | }
1248 |
1249 | if (!current.autoHeight) {
1250 | inner.height( origHeight );
1251 | }
1252 |
1253 | if (current.autoWidth) {
1254 | origWidth = inner.width();
1255 | }
1256 |
1257 | if (current.autoHeight) {
1258 | origHeight = inner.height();
1259 | }
1260 |
1261 | inner.removeClass( 'fancybox-tmp' );
1262 | }
1263 |
1264 | width = getScalar( origWidth );
1265 | height = getScalar( origHeight );
1266 |
1267 | ratio = origWidth / origHeight;
1268 |
1269 | // Calculations for the content
1270 | minWidth = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth);
1271 | maxWidth = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth);
1272 |
1273 | minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight);
1274 | maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight);
1275 |
1276 | // These will be used to determine if wrap can fit in the viewport
1277 | origMaxWidth = maxWidth;
1278 | origMaxHeight = maxHeight;
1279 |
1280 | if (current.fitToView) {
1281 | maxWidth = Math.min(viewport.w - wSpace, maxWidth);
1282 | maxHeight = Math.min(viewport.h - hSpace, maxHeight);
1283 | }
1284 |
1285 | maxWidth_ = viewport.w - wMargin;
1286 | maxHeight_ = viewport.h - hMargin;
1287 |
1288 | if (current.aspectRatio) {
1289 | if (width > maxWidth) {
1290 | width = maxWidth;
1291 | height = getScalar(width / ratio);
1292 | }
1293 |
1294 | if (height > maxHeight) {
1295 | height = maxHeight;
1296 | width = getScalar(height * ratio);
1297 | }
1298 |
1299 | if (width < minWidth) {
1300 | width = minWidth;
1301 | height = getScalar(width / ratio);
1302 | }
1303 |
1304 | if (height < minHeight) {
1305 | height = minHeight;
1306 | width = getScalar(height * ratio);
1307 | }
1308 |
1309 | } else {
1310 | width = Math.max(minWidth, Math.min(width, maxWidth));
1311 |
1312 | if (current.autoHeight && current.type !== 'iframe') {
1313 | inner.width( width );
1314 |
1315 | height = inner.height();
1316 | }
1317 |
1318 | height = Math.max(minHeight, Math.min(height, maxHeight));
1319 | }
1320 |
1321 | // Try to fit inside viewport (including the title)
1322 | if (current.fitToView) {
1323 | inner.width( width ).height( height );
1324 |
1325 | wrap.width( width + wPadding );
1326 |
1327 | // Real wrap dimensions
1328 | width_ = wrap.width();
1329 | height_ = wrap.height();
1330 |
1331 | if (current.aspectRatio) {
1332 | while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) {
1333 | if (steps++ > 19) {
1334 | break;
1335 | }
1336 |
1337 | height = Math.max(minHeight, Math.min(maxHeight, height - 10));
1338 | width = getScalar(height * ratio);
1339 |
1340 | if (width < minWidth) {
1341 | width = minWidth;
1342 | height = getScalar(width / ratio);
1343 | }
1344 |
1345 | if (width > maxWidth) {
1346 | width = maxWidth;
1347 | height = getScalar(width / ratio);
1348 | }
1349 |
1350 | inner.width( width ).height( height );
1351 |
1352 | wrap.width( width + wPadding );
1353 |
1354 | width_ = wrap.width();
1355 | height_ = wrap.height();
1356 | }
1357 |
1358 | } else {
1359 | width = Math.max(minWidth, Math.min(width, width - (width_ - maxWidth_)));
1360 | height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_)));
1361 | }
1362 | }
1363 |
1364 | if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) {
1365 | width += scrollOut;
1366 | }
1367 |
1368 | inner.width( width ).height( height );
1369 |
1370 | wrap.width( width + wPadding );
1371 |
1372 | width_ = wrap.width();
1373 | height_ = wrap.height();
1374 |
1375 | canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight;
1376 | canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight));
1377 |
1378 | $.extend(current, {
1379 | dim : {
1380 | width : getValue( width_ ),
1381 | height : getValue( height_ )
1382 | },
1383 | origWidth : origWidth,
1384 | origHeight : origHeight,
1385 | canShrink : canShrink,
1386 | canExpand : canExpand,
1387 | wPadding : wPadding,
1388 | hPadding : hPadding,
1389 | wrapSpace : height_ - skin.outerHeight(true),
1390 | skinSpace : skin.height() - height
1391 | });
1392 |
1393 | if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) {
1394 | inner.height('auto');
1395 | }
1396 | },
1397 |
1398 | _getPosition: function (onlyAbsolute) {
1399 | var current = F.current,
1400 | viewport = F.getViewport(),
1401 | margin = current.margin,
1402 | width = F.wrap.width() + margin[1] + margin[3],
1403 | height = F.wrap.height() + margin[0] + margin[2],
1404 | rez = {
1405 | position: 'absolute',
1406 | top : margin[0],
1407 | left : margin[3]
1408 | };
1409 |
1410 | if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) {
1411 | rez.position = 'fixed';
1412 |
1413 | } else if (!current.locked) {
1414 | rez.top += viewport.y;
1415 | rez.left += viewport.x;
1416 | }
1417 |
1418 | rez.top = getValue(Math.max(rez.top, rez.top + ((viewport.h - height) * current.topRatio)));
1419 | rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width) * current.leftRatio)));
1420 |
1421 | return rez;
1422 | },
1423 |
1424 | _afterZoomIn: function () {
1425 | var current = F.current;
1426 |
1427 | if (!current) {
1428 | return;
1429 | }
1430 |
1431 | F.isOpen = F.isOpened = true;
1432 |
1433 | F.wrap.css('overflow', 'visible').addClass('fancybox-opened').hide().show(0);
1434 |
1435 | F.update();
1436 |
1437 | // Assign a click event
1438 | if ( current.closeClick || (current.nextClick && F.group.length > 1) ) {
1439 | F.inner.css('cursor', 'pointer').bind('click.fb', function(e) {
1440 | if (!$(e.target).is('a') && !$(e.target).parent().is('a')) {
1441 | e.preventDefault();
1442 |
1443 | F[ current.closeClick ? 'close' : 'next' ]();
1444 | }
1445 | });
1446 | }
1447 |
1448 | // Create a close button
1449 | if (current.closeBtn) {
1450 | $(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) {
1451 | e.preventDefault();
1452 |
1453 | F.close();
1454 | });
1455 | }
1456 |
1457 | // Create navigation arrows
1458 | if (current.arrows && F.group.length > 1) {
1459 | if (current.loop || current.index > 0) {
1460 | $(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev);
1461 | }
1462 |
1463 | if (current.loop || current.index < F.group.length - 1) {
1464 | $(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next);
1465 | }
1466 | }
1467 |
1468 | F.trigger('afterShow');
1469 |
1470 | // Stop the slideshow if this is the last item
1471 | if (!current.loop && current.index === current.group.length - 1) {
1472 |
1473 | F.play( false );
1474 |
1475 | } else if (F.opts.autoPlay && !F.player.isActive) {
1476 | F.opts.autoPlay = false;
1477 |
1478 | F.play(true);
1479 | }
1480 | },
1481 |
1482 | _afterZoomOut: function ( obj ) {
1483 | obj = obj || F.current;
1484 |
1485 | $('.fancybox-wrap').trigger('onReset').remove();
1486 |
1487 | $.extend(F, {
1488 | group : {},
1489 | opts : {},
1490 | router : false,
1491 | current : null,
1492 | isActive : false,
1493 | isOpened : false,
1494 | isOpen : false,
1495 | isClosing : false,
1496 | wrap : null,
1497 | skin : null,
1498 | outer : null,
1499 | inner : null
1500 | });
1501 |
1502 | F.trigger('afterClose', obj);
1503 | }
1504 | });
1505 |
1506 | /*
1507 | * Default transitions
1508 | */
1509 |
1510 | F.transitions = {
1511 | getOrigPosition: function () {
1512 | var current = F.current,
1513 | element = current.element,
1514 | orig = current.orig,
1515 | pos = {},
1516 | width = 50,
1517 | height = 50,
1518 | hPadding = current.hPadding,
1519 | wPadding = current.wPadding,
1520 | viewport = F.getViewport();
1521 |
1522 | if (!orig && current.isDom && element.is(':visible')) {
1523 | orig = element.find('img:first');
1524 |
1525 | if (!orig.length) {
1526 | orig = element;
1527 | }
1528 | }
1529 |
1530 | if (isQuery(orig)) {
1531 | pos = orig.offset();
1532 |
1533 | if (orig.is('img')) {
1534 | width = orig.outerWidth();
1535 | height = orig.outerHeight();
1536 | }
1537 |
1538 | } else {
1539 | pos.top = viewport.y + (viewport.h - height) * current.topRatio;
1540 | pos.left = viewport.x + (viewport.w - width) * current.leftRatio;
1541 | }
1542 |
1543 | if (F.wrap.css('position') === 'fixed' || current.locked) {
1544 | pos.top -= viewport.y;
1545 | pos.left -= viewport.x;
1546 | }
1547 |
1548 | pos = {
1549 | top : getValue(pos.top - hPadding * current.topRatio),
1550 | left : getValue(pos.left - wPadding * current.leftRatio),
1551 | width : getValue(width + wPadding),
1552 | height : getValue(height + hPadding)
1553 | };
1554 |
1555 | return pos;
1556 | },
1557 |
1558 | step: function (now, fx) {
1559 | var ratio,
1560 | padding,
1561 | value,
1562 | prop = fx.prop,
1563 | current = F.current,
1564 | wrapSpace = current.wrapSpace,
1565 | skinSpace = current.skinSpace;
1566 |
1567 | if (prop === 'width' || prop === 'height') {
1568 | ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start);
1569 |
1570 | if (F.isClosing) {
1571 | ratio = 1 - ratio;
1572 | }
1573 |
1574 | padding = prop === 'width' ? current.wPadding : current.hPadding;
1575 | value = now - padding;
1576 |
1577 | F.skin[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) ) );
1578 | F.inner[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) );
1579 | }
1580 | },
1581 |
1582 | zoomIn: function () {
1583 | var current = F.current,
1584 | startPos = current.pos,
1585 | effect = current.openEffect,
1586 | elastic = effect === 'elastic',
1587 | endPos = $.extend({opacity : 1}, startPos);
1588 |
1589 | // Remove "position" property that breaks older IE
1590 | delete endPos.position;
1591 |
1592 | if (elastic) {
1593 | startPos = this.getOrigPosition();
1594 |
1595 | if (current.openOpacity) {
1596 | startPos.opacity = 0.1;
1597 | }
1598 |
1599 | } else if (effect === 'fade') {
1600 | startPos.opacity = 0.1;
1601 | }
1602 |
1603 | F.wrap.css(startPos).animate(endPos, {
1604 | duration : effect === 'none' ? 0 : current.openSpeed,
1605 | easing : current.openEasing,
1606 | step : elastic ? this.step : null,
1607 | complete : F._afterZoomIn
1608 | });
1609 | },
1610 |
1611 | zoomOut: function () {
1612 | var current = F.current,
1613 | effect = current.closeEffect,
1614 | elastic = effect === 'elastic',
1615 | endPos = {opacity : 0.1};
1616 |
1617 | if (elastic) {
1618 | endPos = this.getOrigPosition();
1619 |
1620 | if (current.closeOpacity) {
1621 | endPos.opacity = 0.1;
1622 | }
1623 | }
1624 |
1625 | F.wrap.animate(endPos, {
1626 | duration : effect === 'none' ? 0 : current.closeSpeed,
1627 | easing : current.closeEasing,
1628 | step : elastic ? this.step : null,
1629 | complete : F._afterZoomOut
1630 | });
1631 | },
1632 |
1633 | changeIn: function () {
1634 | var current = F.current,
1635 | effect = current.nextEffect,
1636 | startPos = current.pos,
1637 | endPos = { opacity : 1 },
1638 | direction = F.direction,
1639 | distance = 200,
1640 | field;
1641 |
1642 | startPos.opacity = 0.1;
1643 |
1644 | if (effect === 'elastic') {
1645 | field = direction === 'down' || direction === 'up' ? 'top' : 'left';
1646 |
1647 | if (direction === 'down' || direction === 'right') {
1648 | startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance);
1649 | endPos[ field ] = '+=' + distance + 'px';
1650 |
1651 | } else {
1652 | startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance);
1653 | endPos[ field ] = '-=' + distance + 'px';
1654 | }
1655 | }
1656 |
1657 | // Workaround for http://bugs.jquery.com/ticket/12273
1658 | if (effect === 'none') {
1659 | F._afterZoomIn();
1660 |
1661 | } else {
1662 | F.wrap.css(startPos).animate(endPos, {
1663 | duration : current.nextSpeed,
1664 | easing : current.nextEasing,
1665 | complete : F._afterZoomIn
1666 | });
1667 | }
1668 | },
1669 |
1670 | changeOut: function () {
1671 | var previous = F.previous,
1672 | effect = previous.prevEffect,
1673 | endPos = { opacity : 0.1 },
1674 | direction = F.direction,
1675 | distance = 200;
1676 |
1677 | if (effect === 'elastic') {
1678 | endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px';
1679 | }
1680 |
1681 | previous.wrap.animate(endPos, {
1682 | duration : effect === 'none' ? 0 : previous.prevSpeed,
1683 | easing : previous.prevEasing,
1684 | complete : function () {
1685 | $(this).trigger('onReset').remove();
1686 | }
1687 | });
1688 | }
1689 | };
1690 |
1691 | /*
1692 | * Overlay helper
1693 | */
1694 |
1695 | F.helpers.overlay = {
1696 | defaults : {
1697 | closeClick : true, // if true, fancyBox will be closed when user clicks on the overlay
1698 | speedOut : 200, // duration of fadeOut animation
1699 | showEarly : true, // indicates if should be opened immediately or wait until the content is ready
1700 | css : {}, // custom CSS properties
1701 | locked : !isTouch, // if true, the content will be locked into overlay
1702 | fixed : true // if false, the overlay CSS position property will not be set to "fixed"
1703 | },
1704 |
1705 | overlay : null, // current handle
1706 | fixed : false, // indicates if the overlay has position "fixed"
1707 | el : $('html'), // element that contains "the lock"
1708 |
1709 | // Public methods
1710 | create : function(opts) {
1711 | var parent;
1712 |
1713 | opts = $.extend({}, this.defaults, opts);
1714 |
1715 | if (this.overlay) {
1716 | this.close();
1717 | }
1718 |
1719 | parent = F.coming ? F.coming.parent : opts.parent;
1720 |
1721 | this.overlay = $('
').appendTo( parent && parent.lenth ? parent : 'body' );
1722 | this.fixed = false;
1723 |
1724 | if (opts.fixed && F.defaults.fixed) {
1725 | this.overlay.addClass('fancybox-overlay-fixed');
1726 |
1727 | this.fixed = true;
1728 | }
1729 | },
1730 |
1731 | open : function(opts) {
1732 | var that = this;
1733 |
1734 | opts = $.extend({}, this.defaults, opts);
1735 |
1736 | if (this.overlay) {
1737 | this.overlay.unbind('.overlay').width('auto').height('auto');
1738 |
1739 | } else {
1740 | this.create(opts);
1741 | }
1742 |
1743 | if (!this.fixed) {
1744 | W.bind('resize.overlay', $.proxy( this.update, this) );
1745 |
1746 | this.update();
1747 | }
1748 |
1749 | if (opts.closeClick) {
1750 | this.overlay.bind('click.overlay', function(e) {
1751 | if ($(e.target).hasClass('fancybox-overlay')) {
1752 | if (F.isActive) {
1753 | F.close();
1754 | } else {
1755 | that.close();
1756 | }
1757 |
1758 | return false;
1759 | }
1760 | });
1761 | }
1762 |
1763 | this.overlay.css( opts.css ).show();
1764 | },
1765 |
1766 | close : function() {
1767 | W.unbind('resize.overlay');
1768 |
1769 | if (this.el.hasClass('fancybox-lock')) {
1770 | $('.fancybox-margin').removeClass('fancybox-margin');
1771 |
1772 | this.el.removeClass('fancybox-lock');
1773 |
1774 | W.scrollTop( this.scrollV ).scrollLeft( this.scrollH );
1775 | }
1776 |
1777 | $('.fancybox-overlay').remove().hide();
1778 |
1779 | $.extend(this, {
1780 | overlay : null,
1781 | fixed : false
1782 | });
1783 | },
1784 |
1785 | // Private, callbacks
1786 |
1787 | update : function () {
1788 | var width = '100%', offsetWidth;
1789 |
1790 | // Reset width/height so it will not mess
1791 | this.overlay.width(width).height('100%');
1792 |
1793 | // jQuery does not return reliable result for IE
1794 | if (IE) {
1795 | offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth);
1796 |
1797 | if (D.width() > offsetWidth) {
1798 | width = D.width();
1799 | }
1800 |
1801 | } else if (D.width() > W.width()) {
1802 | width = D.width();
1803 | }
1804 |
1805 | this.overlay.width(width).height(D.height());
1806 | },
1807 |
1808 | // This is where we can manipulate DOM, because later it would cause iframes to reload
1809 | onReady : function (opts, obj) {
1810 | var overlay = this.overlay;
1811 |
1812 | $('.fancybox-overlay').stop(true, true);
1813 |
1814 | if (!overlay) {
1815 | this.create(opts);
1816 | }
1817 |
1818 | if (opts.locked && this.fixed && obj.fixed) {
1819 | obj.locked = this.overlay.append( obj.wrap );
1820 | obj.fixed = false;
1821 | }
1822 |
1823 | if (opts.showEarly === true) {
1824 | this.beforeShow.apply(this, arguments);
1825 | }
1826 | },
1827 |
1828 | beforeShow : function(opts, obj) {
1829 | if (obj.locked && !this.el.hasClass('fancybox-lock')) {
1830 | if (this.fixPosition !== false) {
1831 | $('*').filter(function(){
1832 | return ($(this).css('position') === 'fixed' && !$(this).hasClass("fancybox-overlay") && !$(this).hasClass("fancybox-wrap") );
1833 | }).addClass('fancybox-margin');
1834 | }
1835 |
1836 | this.el.addClass('fancybox-margin');
1837 |
1838 | this.scrollV = W.scrollTop();
1839 | this.scrollH = W.scrollLeft();
1840 |
1841 | this.el.addClass('fancybox-lock');
1842 |
1843 | W.scrollTop( this.scrollV ).scrollLeft( this.scrollH );
1844 | }
1845 |
1846 | this.open(opts);
1847 | },
1848 |
1849 | onUpdate : function() {
1850 | if (!this.fixed) {
1851 | this.update();
1852 | }
1853 | },
1854 |
1855 | afterClose: function (opts) {
1856 | // Remove overlay if exists and fancyBox is not opening
1857 | // (e.g., it is not being open using afterClose callback)
1858 | if (this.overlay && !F.coming) {
1859 | this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this ));
1860 | }
1861 | }
1862 | };
1863 |
1864 | /*
1865 | * Title helper
1866 | */
1867 |
1868 | F.helpers.title = {
1869 | defaults : {
1870 | type : 'float', // 'float', 'inside', 'outside' or 'over',
1871 | position : 'bottom' // 'top' or 'bottom'
1872 | },
1873 |
1874 | beforeShow: function (opts) {
1875 | var current = F.current,
1876 | text = current.title,
1877 | type = opts.type,
1878 | title,
1879 | target;
1880 |
1881 | if ($.isFunction(text)) {
1882 | text = text.call(current.element, current);
1883 | }
1884 |
1885 | if (!isString(text) || $.trim(text) === '') {
1886 | return;
1887 | }
1888 |
1889 | title = $('
' + text + '
');
1890 |
1891 | switch (type) {
1892 | case 'inside':
1893 | target = F.skin;
1894 | break;
1895 |
1896 | case 'outside':
1897 | target = F.wrap;
1898 | break;
1899 |
1900 | case 'over':
1901 | target = F.inner;
1902 | break;
1903 |
1904 | default: // 'float'
1905 | target = F.skin;
1906 |
1907 | title.appendTo('body');
1908 |
1909 | if (IE) {
1910 | title.width( title.width() );
1911 | }
1912 |
1913 | title.wrapInner('
');
1914 |
1915 | //Increase bottom margin so this title will also fit into viewport
1916 | F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) );
1917 | break;
1918 | }
1919 |
1920 | title[ (opts.position === 'top' ? 'prependTo' : 'appendTo') ](target);
1921 | }
1922 | };
1923 |
1924 | // jQuery plugin initialization
1925 | $.fn.fancybox = function (options) {
1926 | var index,
1927 | that = $(this),
1928 | selector = this.selector || '',
1929 | run = function(e) {
1930 | var what = $(this).blur(), idx = index, relType, relVal;
1931 |
1932 | if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) {
1933 | relType = options.groupAttr || 'data-fancybox-group';
1934 | relVal = what.attr(relType);
1935 |
1936 | if (!relVal) {
1937 | relType = 'rel';
1938 | relVal = what.get(0)[ relType ];
1939 | }
1940 |
1941 | if (relVal && relVal !== '' && relVal !== 'nofollow') {
1942 | what = selector.length ? $(selector) : that;
1943 | what = what.filter('[' + relType + '="' + relVal + '"]');
1944 | idx = what.index(this);
1945 | }
1946 |
1947 | options.index = idx;
1948 |
1949 | // Stop an event from bubbling if everything is fine
1950 | if (F.open(what, options) !== false) {
1951 | e.preventDefault();
1952 | }
1953 | }
1954 | };
1955 |
1956 | options = options || {};
1957 | index = options.index || 0;
1958 |
1959 | if (!selector || options.live === false) {
1960 | that.unbind('click.fb-start').bind('click.fb-start', run);
1961 |
1962 | } else {
1963 | D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run);
1964 | }
1965 |
1966 | this.filter('[data-fancybox-start=1]').trigger('click');
1967 |
1968 | return this;
1969 | };
1970 |
1971 | // Tests that need a body at doc ready
1972 | D.ready(function() {
1973 | var w1, w2;
1974 |
1975 | if ( $.scrollbarWidth === undefined ) {
1976 | // http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth
1977 | $.scrollbarWidth = function() {
1978 | var parent = $('
').appendTo('body'),
1979 | child = parent.children(),
1980 | width = child.innerWidth() - child.height( 99 ).innerWidth();
1981 |
1982 | parent.remove();
1983 |
1984 | return width;
1985 | };
1986 | }
1987 |
1988 | if ( $.support.fixedPosition === undefined ) {
1989 | $.support.fixedPosition = (function() {
1990 | var elem = $('
').appendTo('body'),
1991 | fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 );
1992 |
1993 | elem.remove();
1994 |
1995 | return fixed;
1996 | }());
1997 | }
1998 |
1999 | $.extend(F.defaults, {
2000 | scrollbarWidth : $.scrollbarWidth(),
2001 | fixed : $.support.fixedPosition,
2002 | parent : $('body')
2003 | });
2004 |
2005 | //Get real width of page scroll-bar
2006 | w1 = $(window).width();
2007 |
2008 | H.addClass('fancybox-lock-test');
2009 |
2010 | w2 = $(window).width();
2011 |
2012 | H.removeClass('fancybox-lock-test');
2013 |
2014 | $("").appendTo("head");
2015 | });
2016 |
2017 | }(window, document, jQuery));
--------------------------------------------------------------------------------
/source/fancybox/jquery.fancybox.pack.js:
--------------------------------------------------------------------------------
1 | /*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */
2 | (function(s,H,f,w){var K=f("html"),q=f(s),p=f(H),b=f.fancybox=function(){b.open.apply(this,arguments)},J=navigator.userAgent.match(/msie/i),C=null,t=H.createTouch!==w,u=function(a){return a&&a.hasOwnProperty&&a instanceof f},r=function(a){return a&&"string"===f.type(a)},F=function(a){return r(a)&&0
',image:'The requested content cannot be loaded.
Please try again later.
',closeBtn:'