doc.js 32.8 KB
Newer Older
C
Catouse 已提交
1 2
(function(window, $)
{
C
Catouse 已提交
3
    'use strict';
C
Catouse 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16
    // Polyfill
    if (!String.prototype.endsWith) {
        String.prototype.endsWith = function(searchString, position) {
            var subjectString = this.toString();
            if (position === undefined || position > subjectString.length) {
                position = subjectString.length;
            }
            position -= searchString.length;
            var lastIndex = subjectString.indexOf(searchString, position);
            return lastIndex !== -1 && lastIndex === position;
        };
    }

C
Catouse 已提交
17 18 19 20 21 22 23 24 25 26 27 28 29
    if (!String.prototype.startsWith) {
        String.prototype.startsWith = function(searchString, position) {
            position = position || 0;
            return this.lastIndexOf(searchString, position) === position;
        };
    }

    if (!String.prototype.includes) {
        String.prototype.includes = function() {
            return String.prototype.indexOf.apply(this, arguments) !== -1;
        };
    }

C
Catouse 已提交
30
    var saveTraffic = false;
C
Catouse 已提交
31 32
    var debug = 1;
    if(debug) console.error("DEBUG ENABLED.");
C
Catouse 已提交
33 34

    var chapters = {
C
Catouse 已提交
35
        learn: {col: 1}, 
C
Catouse 已提交
36 37 38 39 40 41
        start: {col: 1}, 
        basic: {col: 1}, 
        control: {col: 2}, 
        component: {col: 2}, 
        javascript: {col: 3}, 
        view: {col: 3}
C
Catouse 已提交
42 43
    };
    var LAST_RELOAD_ANIMATE_ID = 'lastReloadAnimate';
C
Catouse 已提交
44
    var LAST_QUERY_ID = 'LAST_QUERY_ID';
C
Catouse 已提交
45
    var INDEX_JSON = 'index.json';
C
Catouse 已提交
46
    var UNDEFINED = undefined;
C
Catouse 已提交
47
    var PAGE_SHOW_FULL = 'page-show-full';
C
Catouse 已提交
48
    var dataset = {
C
Catouse 已提交
49
        // 'index.json': null
C
Catouse 已提交
50 51 52
    };
    if(debug) window.dataset = dataset;

C
Catouse 已提交
53
    var scrollBarWidth = -1;
C
Catouse 已提交
54
    var bestPageWidth = 1120;
C
Catouse 已提交
55 56
    var $body, $window, $grid, $sectionTemplate,
        $queryInput, $chapters, $chaptersCols,
C
Catouse 已提交
57
        $choosedSection, $page, $pageHeader, $pageContent, 
C
Catouse 已提交
58
        $pageContainer, $pageBody, $navbar,
C
Catouse 已提交
59
        $header, $sections, $chapterHeadings; // elements
C
Catouse 已提交
60

C
Catouse 已提交
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
    var checkScrollbar = function()
    {
        if (document.body.clientWidth >= window.innerWidth) return;

        if(scrollBarWidth < 0) {
            var scrollDiv = document.createElement('div');
            scrollDiv.className = 'modal-scrollbar-measure';
            $body.append(scrollDiv);
            scrollBarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
            $body[0].removeChild(scrollDiv);
        }

        if (scrollBarWidth) {
            var bodyPad = parseInt(($body.css('padding-right') || 0), 10);
            $body.css('padding-right', bodyPad + scrollBarWidth);
C
Catouse 已提交
76
            $navbar.css('padding-right', scrollBarWidth);
C
Catouse 已提交
77 78 79 80 81 82
        }
    };

    var resetScrollbar = function()
    {
        $body.css('padding-right', '');
C
Catouse 已提交
83
        $navbar.css('padding-right', '');
C
Catouse 已提交
84 85
    };

C
Catouse 已提交
86 87
    var loadData = function(url, callback, forceLoad) {
        var data = dataset[url];
C
Catouse 已提交
88
        var isFirstLoad = data === UNDEFINED || data === null;
C
Catouse 已提交
89 90
        if(isFirstLoad) {
            data = $.store.get(url, null);
C
Catouse 已提交
91
            dataset[url] = data;
C
Catouse 已提交
92
            if(data !== null) {
C
Catouse 已提交
93
                if(debug) {
C
Catouse 已提交
94
                    console.log('Load data from storage: ', url, ', size:', data.length);
C
Catouse 已提交
95
                }
C
Catouse 已提交
96 97
                callback(data);
            }
C
Catouse 已提交
98 99 100
        } else if(data !== null) {
            if(debug) console.log('Load data from cache: ', url, ', size:', data.length);
            callback(data);
C
Catouse 已提交
101 102
        }

C
Catouse 已提交
103
        if(isFirstLoad || data === null || forceLoad || isFirstLoad || (!saveTraffic)) {
C
Catouse 已提交
104 105 106 107 108 109 110
            var dataType = url.endsWith('.json') ? 'json' : 'html';
            $.get(url, function(remoteData){
                if(!debug && data !== null) {
                    if(dataType === 'json' && $.isPlainObject(remoteData) && data.version && remoteData.version && remoteData.version === data.version) return;
                    if(dataType === 'html' && data === remoteData) return;
                }
                dataset[url] = remoteData;
C
Catouse 已提交
111
                if(debug) {
C
Catouse 已提交
112
                    console.log('Load data from remote: ', url, ', size:', remoteData.length);
C
Catouse 已提交
113
                }
C
Catouse 已提交
114 115 116 117
                callback(remoteData);
                $.store.set(url, remoteData);
            }, dataType);
        }
C
Catouse 已提交
118 119 120 121 122 123 124 125
    };

    var eachSection = function(callback, eachChapterCallback) {
        var docIndex = dataset[INDEX_JSON];
        if (!docIndex) {
            console.error("Document index is empty.");
            return false;
        };
C
Catouse 已提交
126

C
Catouse 已提交
127 128
        $.each(chapters, function(chapterName, chapter){
            if(!docIndex.chapters[chapterName]) return;
C
Catouse 已提交
129 130 131 132 133 134 135 136 137 138 139 140
            $.extend(chapter, docIndex.chapters[chapterName]);
            var sections = chapter.sections;
            var data = null;
            if(eachChapterCallback) {
                data = eachChapterCallback(chapter, sections);
                if(data === false) return false;
            }
            $.each(sections, function(i, section){
                if(callback(chapter, section, data) === false) return false;
            });
        });
        return true;
C
Catouse 已提交
141 142 143 144 145 146 147 148 149 150 151 152 153
    };

    var displaySectionIcon = function($icon, section) {
        $icon.attr('class', 'icon').text('');
        if (section.icon === undefined || section.icon === null || section.icon === "") {
            section.icon = section.name.substr(0, 1).toUpperCase();
        }
        if (section.icon.indexOf('icon-') === 0) {
            $icon.addClass(section.icon);
        } else {
            $icon.addClass('text-icon').text(section.icon);
        }
    };
C
Catouse 已提交
154

C
Catouse 已提交
155
    var displaySection = function() {
C
Catouse 已提交
156
        var order = 0;
C
Catouse 已提交
157 158
        if(eachSection(function(chapter, section, $sectionList){
            var chapterName = chapter.id;
C
Catouse 已提交
159 160
            section.chapter = chapterName;
            var $tpl = $sectionTemplate.clone().attr('id', 'section-' + chapterName + '-' + section.id).data('section', section);
C
Catouse 已提交
161
            $tpl.attr('data-id', section.id).attr('data-chapter', chapterName).attr('data-order', order++);
C
Catouse 已提交
162 163 164
            var $head = $tpl.children('.card-heading');
            $head.find('.name').text(section.name);
            $head.children('.desc').text(section.desc);
C
Catouse 已提交
165
            displaySectionIcon($head.children('.icon'), section);
C
Catouse 已提交
166 167 168 169 170 171 172 173 174 175 176 177 178
            var $topics = $tpl.find('.topics');
            if (section.topics && section.topics.length) {
                for (var tName in section.topics) {
                    var topic = section.topics[tName];
                    topic.id = tName;
                    $topics.append('<li data-id="' + tName + '">' + topic.name + '</li>');
                }
            } else {
                $topics.remove('.card-content');
                $tpl.addClass('without-topics');
            }
            $sectionList.append($tpl.addClass('show'));
        }, function(chapter, sections){
C
Catouse 已提交
179 180
            var $sectionList = chapter.$sections;
            $sectionList.children().remove();
C
Catouse 已提交
181 182
            return $sectionList;
        })) {
C
Catouse 已提交
183
            $body.children('.loader').removeClass('loading');
C
Catouse 已提交
184 185 186 187
            clearTimeout($grid.data(LAST_RELOAD_ANIMATE_ID));
            $grid.data(LAST_RELOAD_ANIMATE_ID, setTimeout(function(){
                $sections = $grid.find('.section').addClass('in');
                $chapterHeadings.addClass('in');
C
Catouse 已提交
188
            }, 100));
C
Catouse 已提交
189 190 191 192 193
        } else if(debug) {
            console.error("Display sections failed.");
        }
    };

C
Catouse 已提交
194 195 196 197 198 199 200 201 202 203
    var scrollToThis = function($container, toTop, callback) {
        if($container === UNDEFINED) $container = $body;
        if(toTop === UNDEFINED || toTop === 'down') {
            toTop = $container.scrollTop() + ($window.height() - $container.offset().top) * 0.8;
        } else if(toTop === 'up') {
            toTop = $container.scrollTop() - ($window.height() - $container.offset().top) * 0.8;
        }
        $container.animate({scrollTop: toTop}, 200, 'swing', callback);
    };

C
Catouse 已提交
204 205 206 207 208 209 210 211 212
    var scrollToSection = function($section) {
        if($section) {
            var top = $section.offset().top;
            var height = $section.outerHeight();
            var winHeight = $window.height();
            var scrollTop = $body.scrollTop();
            if(winHeight < (top + height)) {

            }
C
Catouse 已提交
213 214
        }
    };
C
Catouse 已提交
215

C
Catouse 已提交
216 217 218
    var isChoosedSection = function($section) {
        if($section === UNDEFINED) {
            $section = $choosedSection;
C
Catouse 已提交
219
        }
C
Catouse 已提交
220
        return $section && $section.hasClass('choosed') && $section.hasClass('show');
C
Catouse 已提交
221 222
    };

C
Catouse 已提交
223
    var chooseSection = function($section, keepOtherOpen, notOpenSelf) {
C
Catouse 已提交
224
        if($sections) {
C
Catouse 已提交
225
            if(isChoosedSection($section || null) && !notOpenSelf) {
C
Catouse 已提交
226 227
                $choosedSection = $section.addClass('open');
                scrollToSection($section);
C
Catouse 已提交
228 229 230
                return;
            }
            var isOpened = $section && $section.hasClass('open');
C
Catouse 已提交
231
            $sections.removeClass(keepOtherOpen ? 'choosed' : 'choosed open');
C
Catouse 已提交
232
            if($section && $section.hasClass('section')) {
C
Catouse 已提交
233
                $choosedSection = $section.addClass((notOpenSelf && !isOpened) ? 'choosed' : 'choosed open');
C
Catouse 已提交
234
                scrollToSection($section);
C
Catouse 已提交
235
            }
C
Catouse 已提交
236
        }
C
Catouse 已提交
237
    };
C
Catouse 已提交
238

C
Catouse 已提交
239 240
    var choosePrevSection = function() {
        var $all = $sections.filter('.show');
C
Catouse 已提交
241
        if(isChoosedSection()) {
C
Catouse 已提交
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
            var order = parseInt($choosedSection.data('order'));
            var $section = $choosedSection;
            while((--order) > -1) {
                var $prev = $all.filter('[data-order="' + order + '"]');
                if($prev.length) {
                    $section = $prev;
                    break;
                }
            }
            chooseSection($section);
        } else {
            chooseSection($all.first());
        }
    };

    var chooseNextSection = function() {
        var $all = $sections.filter('.show');
C
Catouse 已提交
259
        if(isChoosedSection()) {
C
Catouse 已提交
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
            var order = parseInt($choosedSection.data('order'));
            var $section = $choosedSection;
            var allCount = $sections.length;
            while((order++) < allCount) {
                var $next = $all.filter('[data-order="' + order + '"]');
                if($next.length) {
                    $section = $next;
                    break;
                }
            }
            chooseSection($section);
        } else {
            chooseSection($all.first());
        }
    };

    var distanceBetweenPoint = function(x1, y1, x2, y2) {
        return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2), 2);
    };

    var chooseLeftSection = function() {
        var $all = $sections.filter('.show');
C
Catouse 已提交
282
        if(isChoosedSection()) {
C
Catouse 已提交
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
            var offset = $choosedSection.offset();
            var left = offset.left - $grid.children('.container').offset().left - 10;
            if(left < 50) {
                choosePrevSection();
                return;
            }
            var top = offset.top;
            left = offset.left;
            var $section = $choosedSection;
            var delta = 99999;
            $all.each(function(){
                var $this = $(this);
                var offset = $this.offset();
                if((offset.left + 50) < left) {
                    var thisDelta = distanceBetweenPoint(offset.left, offset.top, left, top);
                    if(thisDelta < delta) {
                        $section = $this;
                        delta = thisDelta;
                    }
                }
            });
            chooseSection($section);
        } else {
            chooseSection($all.first());
        }
    };

    var chooseRightSection = function() {
        var $all = $sections.filter('.show');
C
Catouse 已提交
312
        if(isChoosedSection()) {
C
Catouse 已提交
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
            var offset = $choosedSection.offset();
            var $container = $grid.children('.container');
            var left = offset.left - $container.offset().left - 10;
            if((left + 20 + $choosedSection.outerWidth() + 50) >= $container.outerWidth()) {
                chooseNextSection();
                return;
            }
            var top = offset.top;
            left = offset.left;
            var $section = $choosedSection;
            var delta = 99999;
            $all.each(function(){
                var $this = $(this);
                var offset = $this.offset();
                if(offset.left > left) {
                    var thisDelta = distanceBetweenPoint(offset.left, offset.top, left, top);
                    if(thisDelta < delta) {
                        $section = $this;
                        delta = thisDelta;
                    }
                }
            });
            chooseSection($section);
        } else {
            chooseSection($all.first());
        }
    };

C
Catouse 已提交
341 342 343 344 345 346 347 348 349 350 351 352
    var resetQuery = function() {
        $chaptersCols.removeClass('hide');
        $chapters.removeClass('hide');
        $sections.addClass('show');
        $chapterHeadings.addClass('show');
        $grid.data(LAST_RELOAD_ANIMATE_ID, setTimeout(function(){
            $sections.addClass('in');
            $chapterHeadings.addClass('in');
        }, 20));
        $body.removeClass('query-enabled');
    };

C
Catouse 已提交
353 354 355 356 357 358 359 360 361
    var query = function(keyString) {
        if(!$sections) return;

        if($queryInput.data('queryString') !== keyString) {
            $queryInput.data('queryString', keyString).val(keyString);
            $grid.css('min-height', $grid.height());
        }

        if(keyString === UNDEFINED || keyString === null || !keyString.length) {
C
Catouse 已提交
362
            resetQuery();
C
Catouse 已提交
363 364 365
            return;
        }

C
Catouse 已提交
366 367
        $body.addClass('query-enabled');

C
Catouse 已提交
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
        var keys = [];
        $.each(keyString.split(' '), function(i, key){
            key = $.trim(key).toLowerCase();
            var keyOption = {origin: key};
            if(key.startsWith('#')) {
                keyOption.type = 'id';
                keyOption.val = key.substr(1);
            } else if(key.startsWith('icon-') || key.startsWith('icon:')) {
                keyOption.type = 'icon';
                keyOption.val = key.substr(5);
            } else if(key.startsWith('i:')) {
                keyOption.type = 'icon';
                keyOption.val = key.substr(1);
            } else if(key.startsWith('ver:')) {
                keyOption.type = 'version';
                keyOption.val = key.substr(4);
            } else if(key.startsWith('v:')) {
                keyOption.type = 'version';
                keyOption.val = key.substr(2);
            } else if(key.startsWith('version:')) {
                keyOption.type = 'version';
                keyOption.val = key.substr(8);
            } else if(key.startsWith('grunt:') || key.startsWith('build:')) {
                keyOption.type = 'build';
                keyOption.val = key.substr(6);
            } else if(key.startsWith('g:') || key.startsWith('b:')) {
                keyOption.type = 'build';
                keyOption.val = key.substr(2);
            } else {
                $.each(chapters, function(name){
                    if(key.startsWith(name + ':')) {
                        keyOption.type = 'id';
                        keyOption.chapter = name;
                        keyOption.val = key.substr(name.length);
                        return false;
                    }
                });
                if(!keyOption.type) {
                    keyOption.type = 'any';
                    keyOption.val = key;
                }
            }
C
Catouse 已提交
410 411 412
            if(keyOption.val.length) {
                keys.push(keyOption);
            }
C
Catouse 已提交
413 414
        });

C
Catouse 已提交
415 416 417 418 419
        if(!keys.length) {
            resetQuery();
            return;
        }

C
Catouse 已提交
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498
        var resultMap = {}, chapterMap = {}, weight, id, chooseThis, chooseThisKey, keyVal, matches, matchType;
        if(eachSection(function(chapter, section){
            chooseThis = true;
            matches = [];
            weight = 0;
            $.each(keys, function(keyIndex, key){
                keyVal = key.val;
                matchType = null;
                chooseThisKey = false;
                switch(key.type) {
                    case 'id':
                        chooseThisKey = (key.chapter ? chapter : section).id.includes(keyVal);
                        if(chooseThisKey) matchType = [key.chapter ? 'chapter' : 'section', 'id'];
                        weight = 100;
                        break;
                    case 'icon':
                        chooseThisKey = section.id === 'icons';
                        if(chooseThisKey) matchType = ['section', 'id'];
                        weight = 100;
                        break;
                    default:
                        if(section.name.toLowerCase().includes(keyVal)) {
                            chooseThisKey = true;
                            matchType = ['section', 'name'];
                            weight = 80;
                            break;
                        }
                        if(chapter.name.toLowerCase().includes(keyVal)) {
                            chooseThisKey = true;
                            matchType = ['chapter', 'name'];
                            weight = 70;
                            break;
                        }
                        if(keyVal.length > 1) {
                            if(section.id.includes(keyVal)) {
                                chooseThisKey = true;
                                matchType = ['section', 'id'];
                                weight = 65;
                                break;
                            }
                            if(chapter.id.includes(keyVal)) {
                                chooseThisKey = true;
                                matchType = ['chapter', 'id'];
                                weight = 60;
                                break;
                            }
                            if($.isArray(section.topics)) {
                                var isBreak = false;
                                $.each(section.topics, function(topicIndex, topic){
                                    if(topic.name && topic.name.toLowerCase().includes(keyVal)) {
                                        chooseThisKey = true;
                                        matchType = ['section', 'topic', topicIndex];
                                        isBreak = true;
                                        weight = 20;
                                        return false;
                                    }
                                });
                                if(isBreak) break;
                            }
                            if(section.desc.toLowerCase().includes(keyVal)) {
                                chooseThisKey = true;
                                matchType = 'section.desc';
                                weight = 30;
                                break;
                            }
                        } else {
                            if(chapter.id.startsWith(keyVal)) {
                                chooseThisKey = true;
                                matchType = ['chapter', 'id'];
                                weight = 60;
                                break;
                            }
                            if(section.id.startsWith(keyVal)) {
                                chooseThisKey = true;
                                matchType = ['section', 'id'];
                                weight = 50;
                                break;
                            }
                        }
C
Catouse 已提交
499
                }
C
Catouse 已提交
500 501 502
                if(!chooseThisKey) {
                    chooseThis = false;
                    return false;
C
Catouse 已提交
503
                } else {
C
Catouse 已提交
504
                    matches.push({key: key, type: matchType});
C
Catouse 已提交
505
                }
C
Catouse 已提交
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
            });

            id = chapter.id + '-' + section.id;
            if(chooseThis) {
                chapterMap[chapter.id]++;
                resultMap[id] = {hidden: false, matches: matches, weight: weight};
            } else {
                resultMap[id] = {hidden: true};
            }
        }, function(chapter){
            chapterMap[chapter.id] = 0;
        })) {
            var $hide = $(), $show = $(), $section, choosedWeight = -1, $choosed;
            $.each(resultMap, function(id, result){
                $section = $('#section-' + id);
                if(result.hidden) {
                    $hide = $hide.add($section);
C
Catouse 已提交
523
                } else {
C
Catouse 已提交
524 525 526 527 528
                    $show = $show.add($section);
                    if(choosedWeight < result.weight) {
                        $choosed = $section;
                        choosedWeight = result.weight;
                    }
C
Catouse 已提交
529
                }
C
Catouse 已提交
530
                chooseSection($choosed);
C
Catouse 已提交
531
            });
C
Catouse 已提交
532 533 534 535 536 537 538 539

            var $chapter, hide, chapter;
            $.each(chapterMap, function(chapterId, resultCount){
                chapter = chapters[chapterId];
                hide = !resultCount;
                chapter.$.toggleClass('hide', hide);
            });
            var $col;
C
Catouse 已提交
540
            var showColCount = 0;
C
Catouse 已提交
541 542
            $chaptersCols.each(function(){
                $col = $(this);
C
Catouse 已提交
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
                var showCol = $col.children('.chapter:not(.hide)').length;
                $col.toggleClass('hide', !showCol);
                if(showCol) {
                    showColCount++;
                    if(!$body.hasClass('compact-mode')) {
                        var showCount = $col.find('.section:not(.hide)').length;
                        if(showCount > 2 && $window.height() < ($header.height() + showCount * 70)) {
                            $body.addClass('compact-mode');
                            setTimeout(function(){
                                $window.scrollTop(1);
                                $body.addClass('compact-mode-in');
                            }, 10);
                        }
                    }
                }
C
Catouse 已提交
558
            });
C
Catouse 已提交
559
            $grid.attr('data-show-col', showColCount);
C
Catouse 已提交
560 561 562

            if($hide.length) {
                $hide.removeClass('in');
C
Catouse 已提交
563
                setTimeout(function(){$hide.removeClass('show');}, 100);
C
Catouse 已提交
564 565 566 567 568
            }
            if($show.length) {
                $show.addClass('show');
                setTimeout(function(){$show.addClass('in');}, 20);
            }
C
Catouse 已提交
569 570

            $window.scrollTop(1);
C
Catouse 已提交
571
            closePage();
C
Catouse 已提交
572 573 574
        } else if(debug) {
            console.error("Query failed with key: ", keys);
        }
C
Catouse 已提交
575 576 577
    };

    var toggleCompactMode = function(toggle, callback) {
C
Catouse 已提交
578 579 580 581
        if(toggle === UNDEFINED) {
            toggle = !$body.hasClass('compact-mode');
        }

C
Catouse 已提交
582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612
        var animateName = 'isScrollAnimating';
        if(toggle) {
            if(!$body.hasClass('compact-mode')) {
                $body.data(animateName, true).addClass('compact-mode')
                setTimeout(function(){
                    $body.addClass('compact-mode-in');
                    $window.scrollTop(1);
                    setTimeout(function(){
                        $body.data(animateName, false);
                        if(callback) callback();
                    }, 500);
                }, 10);
            } else if(callback) {
                callback();
            }
        } else {
            if($body.hasClass('compact-mode')) {
                $body.data(animateName, true).removeClass('compact-mode-in');
                setTimeout(function(){
                    $body.removeClass('compact-mode');
                    $body.data(animateName, false);
                    if(callback) callback();
                }, 500);
            } else if(callback) {
                callback();
            }
        }
    };

    var closePage = function() {
        if($body.hasClass('page-show')) {
C
Catouse 已提交
613 614 615 616
            var style = $page.data('trans-style');
            style['max-height'] = '';
            $page.css(style);
            $body.addClass('page-show-out').removeClass('page-show-in');
C
Catouse 已提交
617
            setTimeout(function(){
C
Catouse 已提交
618
                $body.removeClass('page-show page-show-out');
C
Catouse 已提交
619
                resetScrollbar();
C
Catouse 已提交
620
            }, 300);
C
Catouse 已提交
621
            return true;
C
Catouse 已提交
622
        }
C
Catouse 已提交
623
        return false;
C
Catouse 已提交
624 625
    };

C
Catouse 已提交
626
    var openPage = function($section, section, topic) {
C
Catouse 已提交
627 628
        chooseSection($section, false, true);
        closePage();
C
Catouse 已提交
629

C
Catouse 已提交
630 631 632 633
        $body.attr('data-page-chapter', section.chapter);
        displaySectionIcon($pageHeader.children('.icon'), section);
        $pageHeader.find('.name').text(section.name);
        $pageHeader.children('.desc').text(section.desc);
C
Catouse 已提交
634
        $pageContent.html('');
C
Catouse 已提交
635
        var $loader = $page.addClass('loading').find('.loader').addClass('loading');
C
Catouse 已提交
636 637 638

        loadData(section.url, function(data){
            $page.removeClass('loading');
C
Catouse 已提交
639
            $loader.removeClass('loading');
C
Catouse 已提交
640
            $pageContent.html(data);
C
Catouse 已提交
641
            $queryInput.blur();
C
Catouse 已提交
642 643
            $pageBody.scrollTop(0);
        });
C
Catouse 已提交
644 645 646

        toggleCompactMode(true, function(){
            var offset = $section.offset();
C
Catouse 已提交
647 648 649
            var sectionHeight = $section.outerHeight();
            var style = {
                left: offset.left - $grid.children('.container').offset().left - 6,
C
Catouse 已提交
650 651
                top: offset.top - $window.scrollTop() - 80,
                width: $section.outerWidth(),
C
Catouse 已提交
652 653 654 655 656
                height: sectionHeight,
                'max-height': sectionHeight
            };
            $page.css(style).data('trans-style', style);
            $pageBody.css('width', bestPageWidth);
C
Catouse 已提交
657 658 659 660 661

            checkScrollbar();
            $body.addClass('page-show');
            setTimeout(function(){
                $body.addClass('page-show-in');
C
Catouse 已提交
662 663 664 665 666 667
                if($page.hasClass('loading')) $page.addClass('openning').css('height', 380);
                $pageBody.scrollTop(0);
                setTimeout(function(){
                    $page.removeClass('openning');
                    bestPageWidth = $pageBody.css('width', '').width() + 40;
                }, 310);
C
Catouse 已提交
668 669 670
            }, 10);
        });
    };
C
Catouse 已提交
671

C
Catouse 已提交
672
    var openSection = function(section, topic) {
C
Catouse 已提交
673 674
        section = section || $choosedSection;

C
Catouse 已提交
675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704
        var $section;
        if($.isPlainObject(section)) {
            $section = $('#section-' + section.chapter + '-' + section.id);
        } else {
            var $temp = section;
            section = $temp.data('section');
            $section = $temp;
        }

        var url = section.url;

        if(url === null) {
            if(debug) console.error("Open section stop by null url.");
            return;
        }

        if(!url) {
            url = 'part/' + section.chapter + '-' + section.id + '.html';
            section.url = url;
        }

        url = url.toLowerCase();
        if(url.startsWith('http://') || url.startsWith('https://') ) {
            window.open(url, '_blank');
        } else {
            openPage($section, section, topic);
        }
    };

    var resizePage = function() {
C
Catouse 已提交
705
        if($body.hasClass('page-show-out') || $page.hasClass('loading')) return;
C
Catouse 已提交
706 707 708 709 710 711 712
        var height;
        if($body.hasClass(PAGE_SHOW_FULL)) {
            height = $window.height();
            $pageBody.toggleClass('with-scrollbar', $pageContent.outerHeight() > (height - 40 - $pageHeader.outerHeight()));
        } else {
            height = Math.min($pageContainer.outerHeight(), $pageHeader.outerHeight() + $pageContent.outerHeight() + 50);
        }
C
Catouse 已提交
713 714
        $page.css('height', height);
        console.log('resize page height to ', height);
C
Catouse 已提交
715 716
    };

C
Catouse 已提交
717
    $(function() {
C
Catouse 已提交
718 719 720 721
        var stopPropagation = function(e) {
            e.stopPropagation();
        }

C
Catouse 已提交
722 723
        $window = $(window);
        $body = $('body');
C
Catouse 已提交
724
        $navbar = $('#navbar');
C
Catouse 已提交
725 726
        $grid = $('#grid');
        $header = $('#header');
C
Catouse 已提交
727
        $chaptersCols = $grid.find('.col');
C
Catouse 已提交
728 729
        $page = $('#page');
        $pageHeader = $('#pageHeader');
C
Catouse 已提交
730 731
        $pageContainer = $('#pageContainer');
        $pageContent = $('#pageContent');
C
Catouse 已提交
732 733 734
        $chapters = $grid.find('.chapter');
        $queryInput = $('#searchInput');
        $chapterHeadings = $grid.find('.chapter-heading');
C
Catouse 已提交
735
        $sectionTemplate = $('#sectionTemplate').attr('id', null);
C
Catouse 已提交
736
        $pageBody = $('#pageBody');
C
Catouse 已提交
737 738 739 740 741 742
        $.each(chapters, function(chapterId, chapter){
            chapterId = chapterId.toLowerCase();
            chapter.$ = $('#chapter-' + chapterId);
            chapter.id = chapterId;
            chapter.$sections = $('#sections-' + chapterId);
        });
C
Catouse 已提交
743 744 745
        bestPageWidth = $grid.children('.container').outerWidth();
        $body.toggleClass(PAGE_SHOW_FULL, $.store.get(PAGE_SHOW_FULL, false));
        loadData(INDEX_JSON, displaySection);
C
Catouse 已提交
746 747

        // Bind events
C
Catouse 已提交
748 749 750 751 752
        $(document).on('click', function(e){
            if($body.hasClass('page-show')) {
                closePage();
                return;
            }
C
Catouse 已提交
753 754 755
            chooseSection();
            $sections.removeClass('open');
        });
C
Catouse 已提交
756
        $page.on('click', stopPropagation);
C
Catouse 已提交
757
        $grid.on('click', '.card-heading', function(e) {
C
Catouse 已提交
758
            var $card = $(this).closest('.card');
C
Catouse 已提交
759 760
            if(!$card.hasClass('choosed')) {
                chooseSection($card, true);
C
Catouse 已提交
761 762 763
            } else {
                $card.toggleClass('open');
            }
C
Catouse 已提交
764
            stopPropagation(e);
C
Catouse 已提交
765
        }).on('click', '.card', function(e){
C
Catouse 已提交
766
            chooseSection($(this), true);
C
Catouse 已提交
767 768
            stopPropagation(e);
        }).on('click', '.card-heading > h5 > .name, .card-heading > .icon', function(e){
C
Catouse 已提交
769
            openSection($(this).closest('.section'));
C
Catouse 已提交
770 771 772
            stopPropagation(e);
        }).on('click', '.topics > li', function(e){
            var $li = $(this);
C
Catouse 已提交
773
            openSection($li.closest('.section'), $li.data('id'));
C
Catouse 已提交
774
            stopPropagation(e);
C
Catouse 已提交
775 776 777 778 779 780
        }).on('mouseenter', '.card-heading > h5 > .name, .card-heading > .icon', function(){
            $(this).closest('.card-heading').addClass('hover');
        }).on('mouseleave', '.card-heading > h5 > .name, .card-heading > .icon', function(){
            $(this).closest('.card-heading').removeClass('hover');
        });

C
Catouse 已提交
781 782 783
        $pageContent.on('resize', resizePage);
        $window.resize(resizePage);

C
Catouse 已提交
784 785
        $pageHeader.on('click', '.path-close-btn', function(){
            closePage();
C
Catouse 已提交
786 787 788
        }).on('click', '.path-max-btn', function(){
            $body.toggleClass(PAGE_SHOW_FULL);
            $.store.set(PAGE_SHOW_FULL, $body.hasClass(PAGE_SHOW_FULL));
C
Catouse 已提交
789 790
        });

C
Catouse 已提交
791 792 793
        var scrollHeight = $('#navbar').outerHeight();
        var lastScrollTop;
        $window.on('scroll', function(e){
C
Catouse 已提交
794
            var isScrollAnimating = $body.data('isScrollAnimating');
C
Catouse 已提交
795
            if(isScrollAnimating) {
C
Catouse 已提交
796
                $window.scrollTop(1);
C
Catouse 已提交
797
                return;
C
Catouse 已提交
798 799 800
            }
            lastScrollTop = $window.scrollTop();
            if(lastScrollTop > scrollHeight && !$body.hasClass('compact-mode')) {
C
Catouse 已提交
801
                toggleCompactMode(true);
C
Catouse 已提交
802 803
            } else if($body.hasClass('compact-mode')) {
                if(lastScrollTop < 1) {
C
Catouse 已提交
804
                    toggleCompactMode(false);
C
Catouse 已提交
805 806 807 808
                } else {
                    $header.toggleClass('with-shadow', lastScrollTop > 20);
                }
            }
C
Catouse 已提交
809 810
        }).on('keydown', function(e){
            var code = e.which;
C
Catouse 已提交
811 812
            console.log('keydown', code);
            var isPageNotShow = !$body.hasClass('page-show');
C
Catouse 已提交
813
            if(code === 13) { // Enter
C
Catouse 已提交
814 815
                if(isPageNotShow && isChoosedSection()) {
                    openSection();
C
Catouse 已提交
816 817 818 819 820 821 822
                }
            } else if(code === 27) { // Esc
                if(!closePage()) {
                    if($body.hasClass('input-query-focus')) {
                        query();
                    }
                }
C
Catouse 已提交
823 824 825 826 827 828 829 830
            } else if(code === 32) { // Space
                if(closePage()) {
                } else if(!$body.hasClass('compact-mode')) {
                    toggleCompactMode(true);
                } else if(isChoosedSection()) {
                    openSection();
                }
                e.preventDefault();
C
Catouse 已提交
831 832 833 834 835 836 837
            } else if(code === 37) { // Left
                chooseLeftSection();
                e.preventDefault();
            } else if(code === 39) { // Right
                chooseRightSection();
                e.preventDefault();
            } else if(code === 38) { // Top
C
Catouse 已提交
838 839 840 841 842
                if(isPageNotShow) {
                    choosePrevSection();
                } else {
                    scrollToThis($pageBody, 'up');
                }
C
Catouse 已提交
843
            } else if(code === 40) { // Down
C
Catouse 已提交
844 845 846 847 848
                if(isPageNotShow) {
                    chooseNextSection();
                } else {
                    scrollToThis($pageBody);
                }
C
Catouse 已提交
849 850 851 852 853 854
                e.preventDefault();
            }
        });

        $pageBody.on('scroll', function(e){
            $page.toggleClass('with-shadow', $pageBody.scrollTop() > 20);
C
Catouse 已提交
855
        });
C
Catouse 已提交
856 857 858 859 860 861 862

        $queryInput.on('change keyup paste input propertychange', function(){
            var val = $queryInput.val();
            if(val === $queryInput.data('queryString')) return;
            clearTimeout($queryInput.data(LAST_QUERY_ID));
            $queryInput.data(LAST_QUERY_ID, setTimeout(function(){
                query(val);
C
Catouse 已提交
863
            }, 150));
C
Catouse 已提交
864 865 866 867 868 869 870 871
        }).on('focus', function(){
            $body.addClass('input-query-focus');
            if($queryInput.val() && !$sections.filter('.open').length) {
                chooseSection($sections.filter('.show:first'));
            }
        }).on('blur', function(){
            $body.removeClass('input-query-focus');
        }).on('click', stopPropagation);
C
Catouse 已提交
872 873

        $('[data-toggle="tooltip"]').tooltip({container: 'body'});
C
Catouse 已提交
874
    });
C
Catouse 已提交
875
}(window, jQuery));