BusyBird

 view release on metacpan or  search on metacpan

share/www/static/bootstrap/css/bootstrap.min.css  view on Meta::CPAN

/*!
 * Bootstrap v3.1.1 (http://getbootstrap.com)
 * Copyright 2011-2014 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */

/*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{displa...

share/www/static/busybird.css  view on Meta::CPAN


.bb-status-username {
    font-weight: bold;
    padding: 2px 0 3px 0;
}

.bb-status-created-at {
    font-size: 80%;
}

.bb-status-cursor {
    background-color: #e7e8ec;
}

.bb-status-extension-container {
    padding: 0 0 5px 0;
}

.bb-status-extension-toggler {
    cursor: pointer;
}

.bb-status-extension-toggler:hover {
    background-color: #f4f5f9;
}

.bb-status-extension-pane {
    padding: 5px 0 0 0;
    border-width: 1px 0 0 0;
    border-color: #444;

share/www/static/timeline.js  view on Meta::CPAN

    if(!defined(args.selectorContainer)) {
        throw "selectorContainer param is mandatory";
    }
    if(!defined(args.timeline)) {
        throw "timeline param is mandatory";
    }
    self.sel_container = args.selectorContainer;
    self.timeline = args.timeline;
    self.api_base = defined(args.apiBase) ? args.apiBase : "";
    self.threshold_level = 0;
    self.$cursor = null;
    self.on_threshold_level_changed_callbacks = [];
    
    $(self.sel_container).on("click", ".bb-status", function() {
        self.setCursor(this);
    });
    $(self.sel_container).on("click", ".bb-status-extension-toggler", function(event) {
        if(!now_toggling_extension && $(event.target).closest("a").size() === 0) {
            now_toggling_extension = true;
            self.toggleExtensionPane(this).fin(function() {
                now_toggling_extension = false;

share/www/static/timeline.js  view on Meta::CPAN

    _createWindowAdjuster: function(anchor_position_func) {
        if(!anchor_position_func) {
            return function() {};
        }
        var relative_position_of_anchor;
        relative_position_of_anchor = anchor_position_func() - $(window).scrollTop();
        return function() {
            $(window).scrollTop(anchor_position_func() - relative_position_of_anchor);
        };
    },
    _scanStatusesForDisplayActions: function($statuses, threshold_level, enable_animation, cursor_index) {
        var ACTION_STAY_VISIBLE = 0;
        var ACTION_STAY_INVISIBLE = 1;
        var ACTION_BECOME_VISIBLE = 2;
        var ACTION_BECOME_INVISIBLE = 3;
        var final_result = { // ** return this struct from the promise
            hiddenHeaderList: [],
            domsAnimateToggle: [],
            domsImmediateToggle: [],
            domAnchorElem: null
        };
        var metrics_list = [];
        var next_seq_invisible_entries = [];
        var prev_pos = 0;
        var win_dim = {"top": $(window).scrollTop(), "range": $(window).height()};
        if(!cursor_index) cursor_index = 0;
        return bb.blockEach($statuses.filter(".bb-status").get(), 150, function(status_block, block_start_index) {
            $.each(status_block, function(index_in_block, cur_entry) {
                var cur_index = block_start_index + index_in_block;
                var $cur_entry = $(cur_entry);
                var entry_level = $cur_entry.data('bb-status-level');
                var cur_is_visible = ($cur_entry.css('display') !== 'none');
                var cur_pos = (cur_is_visible ? $cur_entry.offset().top : prev_pos);
                var metric = {
                    status_entry: cur_entry,
                    action: null,
                    win_dist: 0,
                    cursor_index_dist: 0
                };
                if(entry_level >= threshold_level) {
                    metric.action = (cur_is_visible ? ACTION_STAY_VISIBLE : ACTION_BECOME_VISIBLE);
                    if(next_seq_invisible_entries.length > 0) {
                        final_result.hiddenHeaderList.push({'$followed_by': $cur_entry, 'entries': next_seq_invisible_entries});
                        next_seq_invisible_entries = [];
                    }
                }else {
                    metric.action = (cur_is_visible ? ACTION_BECOME_INVISIBLE : ACTION_STAY_INVISIBLE);
                    next_seq_invisible_entries.push($cur_entry);
                }
                metric.win_dist = bb.distanceRanges(win_dim.top, win_dim.range, cur_pos, cur_is_visible ? $cur_entry.height() : 0);
                metric.cursor_index_dist = Math.abs(cur_index - cursor_index);
                prev_pos = cur_pos;
                metrics_list.push(metric);
            });
        }).then(function() {
            var animate_count_max = enable_animation ? selfclass.ANIMATE_STATUS_MAX_NUM : 0;
            var animate_count = 0;
            if(next_seq_invisible_entries.length > 0) {
                final_result.hiddenHeaderList.push({'$followed_by': null, 'entries': next_seq_invisible_entries});
            }
            metrics_list = metrics_list.sort(function (a, b) {
                if(a.win_dist !== b.win_dist) {
                    return a.win_dist - b.win_dist;
                }
                return a.cursor_index_dist - b.cursor_index_dist;
            });
            $.each(metrics_list, function(metrics_index, metric) {
                var target_container;
                if(final_result.domAnchorElem === null && metric.action === ACTION_STAY_VISIBLE) {
                    final_result.domAnchorElem = metric.status_entry;
                }
                if(metric.action === ACTION_STAY_VISIBLE || metric.action === ACTION_STAY_INVISIBLE) {
                    return true;
                }
                if(animate_count < animate_count_max) {

share/www/static/timeline.js  view on Meta::CPAN

                    target_container = final_result.domsAnimateToggle;
                }else {
                    target_container = final_result.domsImmediateToggle;
                }
                target_container.push(metric.status_entry);
            });
            return final_result;
        });
    },
    setDisplayByThreshold: function(args) {
        // @params: args.$statuses, args.threshold, args.enableAnimation, args.enableWindowAdjust, args.cursorIndex
        // @returns: promise for completion event.
        var window_adjuster = function(){};
        return Q.fcall(function() {
            if(!defined(args.$statuses)) {
                throw "$statuses param is mandatory";
            }
            if(!defined(args.threshold)) {
                throw "threshold param is mandatory";
            }
            return selfclass._scanStatusesForDisplayActions(args.$statuses, args.threshold, args.enableAnimation, args.cursorIndex);
        }).then(function(action_description) {
            var promise_hidden_statuses, promise_animation, promise_immediate;
            var $anchor_element;
            var anchor_position_function = null;
            if(args.enableWindowAdjust) {
                if(action_description.domAnchorElem) {
                    $anchor_element = $(action_description.domAnchorElem);
                    anchor_position_function = function() {
                        return $anchor_element.offset().top;
                    };

share/www/static/timeline.js  view on Meta::CPAN

            };
            return makeRequest();
        });
    }
}); selfclass.prototype = {
    _setDisplayImmediately: function($target_statuses) {
        var self = this;
        var args = {
            $statuses: $target_statuses,
            threshold: self.threshold_level,
            cursorIndex: self._getCursorIndex(),
        };
        return selfclass.setDisplayByThreshold(args);
    },
    _getLoadStatusesURL: function() {
        return this.api_base + "/timelines/" + this.timeline + "/statuses.html";
    },
    _getStatuses: function() {
        return $(this.sel_container).children(".bb-status");
    },
    _ackStatuses: function(acked_statuses_dom, set_max_id) {

share/www/static/timeline.js  view on Meta::CPAN

        });
    },
    _isValidForCursor: function($elem) {
        var self = this;
        return ($elem.hasClass("bb-status") && $elem.data("bb-status-level") >= self.threshold_level);
    },
    _adjustCursor: function() {
        var self = this;
        var $statuses;
        var $next_candidate, $prev_candidate;
        if(!defined(self.$cursor)) {
            $statuses = self._getStatuses();
            if($statuses.size() === 0) return;
            self.setCursor($statuses.get(0));
        }
        if(self._isValidForCursor(self.$cursor)) {
            return;
        }
        $next_candidate = self.$cursor;
        $prev_candidate = self.$cursor;
        while(true) {
            $next_candidate = $next_candidate.next();
            $prev_candidate = $prev_candidate.prev();
            if($next_candidate.size() === 0 && $prev_candidate.size() === 0) {
                return;
            }
            if($next_candidate.size() === 1 && self._isValidForCursor($next_candidate.eq(0))) {
                self.setCursor($next_candidate.get(0));
                return;
            }
            if($prev_candidate.size() === 1 && self._isValidForCursor($prev_candidate.eq(0))) {
                self.setCursor($prev_candidate.get(0));
                return;
            }
        }
    },
    _getCursorIndex: function() {
        var self = this;
        if(!defined(self.$cursor)) return -1;
        var $statuses = self._getStatuses();
        if($statuses.size() === 0) return -1;
        return $statuses.index(self.$cursor);
    },
    appendStatuses: function(added_statuses_dom) {
        // @returns: promise resolved when done.
        return this._addStatuses(added_statuses_dom, false);
    },
    prependStatuses: function(added_statuses_dom) {
        // @returns: promise resolved when done.
        return this._addStatuses(added_statuses_dom, true);
    },
    setThresholdLevel: function(new_threshold) {

share/www/static/timeline.js  view on Meta::CPAN

        if(old_threshold !== new_threshold) {
            $.each(self.on_threshold_level_changed_callbacks, function(i, callback) {
                callback(new_threshold);
            });
        }
        return selfclass.setDisplayByThreshold({
            $statuses: $(self.sel_container).children(),
            threshold: self.threshold_level,
            enableAnimation: true,
            enableWindowAdjust: true,
            cursorIndex: self._getCursorIndex()
        });
    },
    getThresholdLevel: function() {
        return this.threshold_level;
    },
    getTimelineName: function() { return this.timeline },
    getAPIBase: function() { return this.api_base },
    loadUnackedStatuses: function() {
        // @returns: promise with the following object
        //           { maxReached: (boolean), statuses: (array of status DOM elements loaded) }

share/www/static/timeline.js  view on Meta::CPAN

        var $acked_new_statuses_label = $(self.sel_container).find(".bb-status-new-label");
        return selfclass.loadStatuses({
            apiURL: self._getLoadStatusesURL(), countPerPage: selfclass.LOAD_UNACKED_STATUSES_COUNT_PER_PAGE,
            maxPageNum: selfclass.LOAD_UNACKED_STATUSES_MAX_PAGE_NUM, ackState: "unacked"
        }).then(function(result) {
            load_result = result;
            return self._ackStatuses(load_result.statuses, load_result.maxReached);
        }).then(function() {
            return self.prependStatuses(load_result.statuses);
        }).then(function() {
            if(!defined(self.$cursor)) {
                self._adjustCursor();
            }
            $acked_new_statuses_label.remove();
            return {maxReached: load_result.maxReached, statuses: load_result.statuses};
        });
    },
    loadMoreStatuses: function() {
        // @returns: promise resolved when done
        var self = this;
        var start_id = null;

share/www/static/timeline.js  view on Meta::CPAN

                startMaxID: start_id, maxPageNum: 1
            });
        }).then(function(result) {
            var added_statuses = result.statuses;
            if(defined(start_id) && added_statuses.length > 0
               && selfclass._getStatusID($(added_statuses[0])) === start_id) {
                added_statuses.shift();
            }
            return self.appendStatuses(result.statuses);
        }).then(function() {
            if(!defined(self.$cursor)) {
                self._adjustCursor();
            }
        });
    },
    loadInit: function() {
        // @returns: promise with the following object
        //           { maxReached: (boolean), statuses: (array of unacked status DOM elements loaded) }
        var self = this;
        var unacked_load_result;
        return self.loadUnackedStatuses().then(function(result) {
            unacked_load_result = result;
            if(!result.maxReached) {
                return self.loadMoreStatuses();
            }
        }).then(function() {
            return unacked_load_result;
        });
    },
    setCursor: function(cursor_dom) {
        var self = this;
        if(defined(self.$cursor)) {
            self.$cursor.removeClass("bb-status-cursor");
        }
        self.$cursor = $(cursor_dom);
        self.$cursor.addClass("bb-status-cursor");
    },
    listenOnThresholdLevelChanged: function(callback) {
        // @params: callback (function(new_threshold) returning anything)
        this.on_threshold_level_changed_callbacks.push(callback);
    },
    _getWindowAdjusterForExtensionPane: function($pane) {
        // @return: a window adjuster function that keeps the closing
        // extension pane near the center of the screen as mush as
        // possible.
        var self = this;

xt/js/qunit.css  view on Meta::CPAN

	padding: 0.4em 0.5em 0.4em 2.5em;
	border-bottom: 1px solid #fff;
	list-style-position: inside;
}

#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running  {
	display: none;
}

#qunit-tests li strong {
	cursor: pointer;
}

#qunit-tests li a {
	padding: 0.5em;
	color: #c2ccd1;
	text-decoration: none;
}
#qunit-tests li a:hover,
#qunit-tests li a:focus {
	color: #000;

xt/js/status_container.html  view on Meta::CPAN

        ok(true, "reason: " + reason);
    }).then(function() {
        start();
    });
});

(function() {
    var con;
    var old_animation_duration;
    var getCursorId = function() {
        var $cursor_status = $("#bb-status-container").find(".bb-status-cursor");
        if($cursor_status.size() === 0) return null;
        return $cursor_status.find(".bb-status-id").text();
    };
    var setCursorToIndex = function(index) {
        var next_cursor = $("#bb-status-container").find(".bb-status").get(index);
        con.setCursor(next_cursor);
    };
    module("move cursor as threshold level changes", {
        setup: function() {
            stop();
            con = setupContainer();
            old_animation_duration = bb.StatusContainer.ANIMATE_STATUS_DURATION;
            bb.StatusContainer.ANIMATE_STATUS_DURATION = 10;
            appendStatusesFromMeta(con, [
                {id: 0, level: 1},
                {id: 1, level: 0},
                {id: 2, level: 2},
                {id: 3, level: 1},
                {id: 4, level: 0},
                {id: 5, level: 0},
                {id: 6, level: 1},
                {id: 7, level: 2}
            ]).then(function() { start() });
        },
        teardown: function() {
            bb.StatusContainer.ANIMATE_STATUS_DURATION = old_animation_duration;
        },
    });
    asyncTest("initially, cursor is at the top", function() {
        con.setThresholdLevel(0).then(function() {
            is(getCursorId(), "0", "cursor is at the top");
        }, function() { ok(false, "should not fail") }).then(function() {
            start();
        });
    });
    asyncTest("cursor stays when visible", function() {
        setCursorToIndex(6);
        con.setThresholdLevel(1).then(function() {
            is(getCursorId(), "6", "cursor stays at ID = 6");
        }, function() { ok(false, "should not fail") }).then(function() {
            start();
        });
    });
    asyncTest("cursor moves when the status gets invisible (upward)", function() {
        setCursorToIndex(4);
        con.setThresholdLevel(2).then(function() {
            is(getCursorId(), "2", "cursor moves ID 4 -> 2");
        }, function() { ok(false, "should not fail") }).then(function() {
            start();
        });
    });
    asyncTest("cursor moves when the status gets invisible (downward)", function() {
        setCursorToIndex(5);
        con.setThresholdLevel(2).then(function() {
            is(getCursorId(), "7", "cursor moves ID 5 -> 7");
        }, function() { ok(false, "should not fail") }).then(function() {
            start();
        });
    });
    asyncTest("cursor stays when all statuses get invisible", function() {
        setCursorToIndex(4);
        con.setThresholdLevel(100).then(function() {
            is(getCursorId(), "4", "cursor stays at ID = 4");
        }, function() { ok(false, "should not fail") }).then(function() {
            start();
        });
    });
    asyncTest("cursor moves downward when top statuses get invisible", function() {
        setCursorToIndex(0);
        con.setThresholdLevel(2).then(function() {
            is(getCursorId(), "2", "cursor moves ID 0 -> 2");
        }, function() { ok(false, "should not fail") }).then(function() {
            start();
        });
    });
})();

module("StatusesSummary");
test("StatusesSummary", function() {
    var summary;
    var next_id = 0;



( run in 0.269 second using v1.01-cache-2.11-cpan-4d50c553e7e )