diff --git a/.gitignore b/.gitignore
index bfad355..110f9d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
static/css/*
-!static/css/lib/*
+!lib
*.swp
.sass-cache
diff --git a/app.py b/app.py
index 0dba068..274daac 100644
--- a/app.py
+++ b/app.py
@@ -22,7 +22,7 @@ database = Database()
@app.route("/")
def index():
- return render_template("index.html", typeahead_languages=LANGS)
+ return render_template("index.html", autocomplete_languages=LANGS)
@app.route("/search.json")
def search():
diff --git a/bitshift/crawler/crawl.py b/bitshift/crawler/crawl.py
index 40238af..2e5ace5 100644
--- a/bitshift/crawler/crawl.py
+++ b/bitshift/crawler/crawl.py
@@ -39,6 +39,7 @@ def crawl():
indexer.GitIndexer(repo_clone_queue, run_event)]
parse_servers = start_parse_servers()
+ time.sleep(5)
for thread in threads:
thread.start()
diff --git a/bitshift/crawler/indexer.py b/bitshift/crawler/indexer.py
index 209078d..b35559a 100644
--- a/bitshift/crawler/indexer.py
+++ b/bitshift/crawler/indexer.py
@@ -33,6 +33,7 @@ class GitRepository(object):
repository belongs to (eg, GitHub, BitBucket).
:ivar rank: (float) The rank of the repository, as assigned by
:class:`crawler.GitHubCrawler`.
+ :ivar dirname: (str) The repository's on-disk directory name.
"""
def __init__(self, url, name, framework_name, rank):
@@ -54,6 +55,7 @@ class GitRepository(object):
self.name = name
self.framework_name = framework_name
self.rank = rank
+ self.dirname = name.replace("-", "--").replace("/", "-")
class GitIndexer(threading.Thread):
"""
@@ -125,19 +127,14 @@ class GitIndexer(threading.Thread):
:type repo_url: :class:`GitRepository`
"""
- with _ChangeDir("%s/%s" % (GIT_CLONE_DIR, repo.name)):
+ with _ChangeDir("%s/%s" % (GIT_CLONE_DIR, repo.dirname)):
try:
self._insert_repository_codelets(repo)
except Exception:
self._logger.exception("Exception raised while indexing:")
finally:
- if os.path.isdir("%s/%s" % (GIT_CLONE_DIR, repo.name)):
- if len([obj for obj in os.listdir('.') if
- os.path.isdir(obj)]) <= 1:
- shutil.rmtree("%s/%s" % (
- GIT_CLONE_DIR, repo.name.split("/")[0]))
- else:
- shutil.rmtree("%s/%s" % (GIT_CLONE_DIR, repo.name))
+ if os.path.isdir("%s/%s" % (GIT_CLONE_DIR, repo.dirname)):
+ shutil.rmtree("%s/%s" % (GIT_CLONE_DIR, repo.dirname))
def _insert_repository_codelets(self, repo):
"""
@@ -167,9 +164,9 @@ class GitIndexer(threading.Thread):
authors = [(self._decode(author), None) for author in
commits_meta[filename]["authors"]]
- codelet = Codelet("%s:%s" % (repo.name, filename), source, filename,
- None, authors, self._generate_file_url(filename,
- repo.url, repo.framework_name),
+ url = self._generate_file_url(filename, repo.url, repo.framework_name)
+ codelet = Codelet("%s: %s" % (repo.name, filename), source,
+ filename, None, authors, url,
commits_meta[filename]["time_created"],
commits_meta[filename]["time_last_modified"],
repo.rank)
@@ -437,37 +434,20 @@ class _GitCloner(threading.Thread):
"""
GIT_CLONE_TIMEOUT = 500
-
queue_percent_full = (float(self.index_queue.qsize()) /
- self.index_queue.maxsize) * 100
-
- exit_code = None
- command = ("perl -e 'alarm shift @ARGV; exec @ARGV' %d git clone"
- " --single-branch %s %s/%s || pkill -f git")
-
- command_attempt = 0
- while exit_code is None:
- try:
- exit_code = subprocess.call(command % (GIT_CLONE_TIMEOUT,
- repo.url, GIT_CLONE_DIR, repo.name), shell=True)
- except Exception:
- time.sleep(1)
- command_attempt += 1
- if command_attempt == 20:
- break
- else:
- continue
- else:
- break
-
- if exit_code != 0:
- if os.path.isdir("%s/%s" % (GIT_CLONE_DIR, repo.name)):
- shutil.rmtree("%s/%s" % (GIT_CLONE_DIR, repo.name))
+ self.index_queue.maxsize) * 100
+
+ command = ["perl", "-e", "alarm shift @ARGV; exec @ARGV",
+ str(GIT_CLONE_TIMEOUT), "git", "clone", "--single-branch",
+ repo.url, GIT_CLONE_DIR + "/" + repo.dirname]
+ if subprocess.call(command) != 0:
+ subprocess.call(["pkill", "-f", "git"]) # This makes Ben K upset
+ if os.path.isdir("%s/%s" % (GIT_CLONE_DIR, repo.dirname)):
+ shutil.rmtree("%s/%s" % (GIT_CLONE_DIR, repo.dirname))
return
while self.index_queue.full():
time.sleep(THREAD_QUEUE_SLEEP)
-
self.index_queue.put(repo)
class _ChangeDir(object):
diff --git a/bitshift/database/__init__.py b/bitshift/database/__init__.py
index 5f483f3..23b190c 100644
--- a/bitshift/database/__init__.py
+++ b/bitshift/database/__init__.py
@@ -131,7 +131,7 @@ class Database(object):
def _decompose_url(self, cursor, url):
"""Break up a URL into an origin (with a URL base) and a suffix."""
- query = """SELECT origin_id, SUBSTR(?, LENGTH(origin_url_base))
+ query = """SELECT origin_id, SUBSTR(?, LENGTH(origin_url_base) + 1)
FROM origins
WHERE origin_url_base IS NOT NULL
AND ? LIKE CONCAT(origin_url_base, "%")"""
diff --git a/bitshift/database/migration.py b/bitshift/database/migration.py
index 9a74a18..730790f 100644
--- a/bitshift/database/migration.py
+++ b/bitshift/database/migration.py
@@ -3,7 +3,7 @@ Contains information about database schema versions, and SQL queries to update
between them.
"""
-VERSION = 8
+VERSION = 10
MIGRATIONS = [
# 1 -> 2
@@ -100,6 +100,28 @@ MIGRATIONS = [
[
"""ALTER TABLE `origins`
DROP COLUMN `origin_image`"""
+ ],
+ # 8 -> 9
+ [
+ """DELIMITER //
+ CREATE PROCEDURE `empty_database`()
+ BEGIN
+ DELETE FROM `codelets`;
+ DELETE FROM `code`;
+ DELETE FROM `cache`;
+ ALTER TABLE `codelets` AUTO_INCREMENT = 1;
+ ALTER TABLE `authors` AUTO_INCREMENT = 1;
+ ALTER TABLE `symbols` AUTO_INCREMENT = 1;
+ ALTER TABLE `symbol_locations` AUTO_INCREMENT = 1;
+ END//
+ DELIMITER ;"""
+ ],
+ # 9 -> 10
+ [
+ """ALTER TABLE `symbol_locations`
+ MODIFY COLUMN `sloc_col` INT UNSIGNED DEFAULT NULL,
+ MODIFY COLUMN `sloc_end_row` INT UNSIGNED DEFAULT NULL,
+ MODIFY COLUMN `sloc_end_col` INT UNSIGNED DEFAULT NULL"""
]
]
diff --git a/bitshift/database/schema.sql b/bitshift/database/schema.sql
index 913a365..6102fe8 100644
--- a/bitshift/database/schema.sql
+++ b/bitshift/database/schema.sql
@@ -1,4 +1,4 @@
--- Schema version 8
+-- Schema version 10
CREATE DATABASE `bitshift` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
USE `bitshift`;
@@ -6,7 +6,7 @@ USE `bitshift`;
CREATE TABLE `version` (
`version` INT UNSIGNED NOT NULL
) ENGINE=InnoDB;
-INSERT INTO `version` VALUES (8);
+INSERT INTO `version` VALUES (10);
CREATE TABLE `origins` (
`origin_id` TINYINT UNSIGNED NOT NULL AUTO_INCREMENT,
@@ -77,9 +77,9 @@ CREATE TABLE `symbol_locations` (
`sloc_symbol` BIGINT UNSIGNED NOT NULL,
`sloc_type` TINYINT UNSIGNED NOT NULL,
`sloc_row` INT UNSIGNED NOT NULL,
- `sloc_col` INT UNSIGNED NOT NULL,
- `sloc_end_row` INT UNSIGNED NOT NULL,
- `sloc_end_col` INT UNSIGNED NOT NULL,
+ `sloc_col` INT UNSIGNED DEFAULT NULL,
+ `sloc_end_row` INT UNSIGNED DEFAULT NULL,
+ `sloc_end_col` INT UNSIGNED DEFAULT NULL,
PRIMARY KEY (`sloc_id`),
FOREIGN KEY (`sloc_symbol`)
REFERENCES `symbols` (`symbol_id`)
@@ -107,6 +107,19 @@ CREATE TABLE `cache_data` (
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB;
+DELIMITER //
+CREATE PROCEDURE `empty_database`()
+ BEGIN
+ DELETE FROM `codelets`;
+ DELETE FROM `code`;
+ DELETE FROM `cache`;
+ ALTER TABLE `codelets` AUTO_INCREMENT = 1;
+ ALTER TABLE `authors` AUTO_INCREMENT = 1;
+ ALTER TABLE `symbols` AUTO_INCREMENT = 1;
+ ALTER TABLE `symbol_locations` AUTO_INCREMENT = 1;
+ END//
+DELIMITER ;
+
CREATE EVENT `flush_cache`
ON SCHEDULE EVERY 1 HOUR
DO
diff --git a/bitshift/languages.py b/bitshift/languages.py
index d6395bb..e809d44 100644
--- a/bitshift/languages.py
+++ b/bitshift/languages.py
@@ -8,7 +8,8 @@ def _load_langs():
filename = path.join(path.dirname(__file__), "languages.yml")
with open(filename) as fp:
data = yaml.load(fp)["languages"]
- langs = [it.keys()[0] if isinstance(it, dict) else it for it in data]
+ langs = [(it.keys()[0] if isinstance(it, dict) else it).encode("utf8")
+ for it in data]
all_langs = {}
for i, lang in enumerate(data):
if isinstance(lang, dict):
diff --git a/parsers/java/src/main/java/com/bitshift/parsing/parsers/JavaParser.java b/parsers/java/src/main/java/com/bitshift/parsing/parsers/JavaParser.java
index 989c0dd..8b6b2f0 100644
--- a/parsers/java/src/main/java/com/bitshift/parsing/parsers/JavaParser.java
+++ b/parsers/java/src/main/java/com/bitshift/parsing/parsers/JavaParser.java
@@ -80,7 +80,7 @@ public class JavaParser extends Parser {
int sl = this.root.getLineNumber(node.getStartPosition());
int sc = this.root.getColumnNumber(node.getStartPosition());
- Integer el = -1;
+ Integer el = sl;
Integer ec = -1;
if (statements.size() > 0) {
@@ -110,7 +110,7 @@ public class JavaParser extends Parser {
int sl = this.root.getLineNumber(node.getStartPosition());
int sc = this.root.getColumnNumber(node.getStartPosition());
- data.put("coord", Symbols.createCoord(sl, sc, -1, -1));
+ data.put("coord", Symbols.createCoord(sl, sc, sl, -1));
data.put("name", name);
this._cache.push(data);
return true;
@@ -140,7 +140,7 @@ public class JavaParser extends Parser {
int sl = this.root.getLineNumber(node.getStartPosition());
int sc = this.root.getColumnNumber(node.getStartPosition());
- data.put("coord", Symbols.createCoord(sl, sc, -1, -1));
+ data.put("coord", Symbols.createCoord(sl, sc, sl, -1));
this._cache.push(data);
return true;
}
@@ -161,7 +161,7 @@ public class JavaParser extends Parser {
int sl = this.root.getLineNumber(node.getStartPosition());
int sc = this.root.getColumnNumber(node.getStartPosition());
- data.put("coord", Symbols.createCoord(sl, sc, -1, -1));
+ data.put("coord", Symbols.createCoord(sl, sc, sl, -1));
this._cache.push(data);
return true;
}
diff --git a/static/css/lib/github.css b/static/css/lib/github.css
new file mode 100644
index 0000000..723432c
--- /dev/null
+++ b/static/css/lib/github.css
@@ -0,0 +1,65 @@
+td.linenos { background: rgba(65,131,196,0.05); padding-right: 10px; border-right: 1px solid #bbb; }
+span.lineno { background: rgba(65,131,196,0.05); padding: 0 5px 0 5px; }
+pre { line-height: 125% }
+.highlighttable { background-color: #fff; padding-left: 10px; width: inherit; height: inherit; }
+.hll { display: block }
+.c { color: #999988; font-style: italic } /* Comment */
+.err { color: #a61717; background-color: #e3d2d2 } /* Error */
+.k { color: #000000; font-weight: bold } /* Keyword */
+.o { color: #000000; font-weight: bold } /* Operator */
+.cm { color: #999988; font-style: italic } /* Comment.Multiline */
+.cp { color: #999999; font-weight: bold; font-style: italic } /* Comment.Preproc */
+.c1 { color: #999988; font-style: italic } /* Comment.Single */
+.cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
+.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
+.ge { color: #000000; font-style: italic } /* Generic.Emph */
+.gr { color: #aa0000 } /* Generic.Error */
+.gh { color: #999999 } /* Generic.Heading */
+.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
+.go { color: #888888 } /* Generic.Output */
+.gp { color: #555555 } /* Generic.Prompt */
+.gs { font-weight: bold } /* Generic.Strong */
+.gu { color: #aaaaaa } /* Generic.Subheading */
+.gt { color: #aa0000 } /* Generic.Traceback */
+.kc { color: #000000; font-weight: bold } /* Keyword.Constant */
+.kd { color: #000000; font-weight: bold } /* Keyword.Declaration */
+.kn { color: #000000; font-weight: bold } /* Keyword.Namespace */
+.kp { color: #000000; font-weight: bold } /* Keyword.Pseudo */
+.kr { color: #000000; font-weight: bold } /* Keyword.Reserved */
+.kt { color: #445588; font-weight: bold } /* Keyword.Type */
+.m { color: #009999 } /* Literal.Number */
+.s { color: #d01040 } /* Literal.String */
+.na { color: #008080 } /* Name.Attribute */
+.nb { color: #0086B3 } /* Name.Builtin */
+.nc { color: #445588; font-weight: bold } /* Name.Class */
+.no { color: #008080 } /* Name.Constant */
+.nd { color: #3c5d5d; font-weight: bold } /* Name.Decorator */
+.ni { color: #800080 } /* Name.Entity */
+.ne { color: #990000; font-weight: bold } /* Name.Exception */
+.nf { color: #990000; font-weight: bold } /* Name.Function */
+.nl { color: #990000; font-weight: bold } /* Name.Label */
+.nn { color: #555555 } /* Name.Namespace */
+.nt { color: #000080 } /* Name.Tag */
+.nv { color: #008080 } /* Name.Variable */
+.ow { color: #000000; font-weight: bold } /* Operator.Word */
+.w { color: #bbbbbb } /* Text.Whitespace */
+.mf { color: #009999 } /* Literal.Number.Float */
+.mh { color: #009999 } /* Literal.Number.Hex */
+.mi { color: #009999 } /* Literal.Number.Integer */
+.mo { color: #009999 } /* Literal.Number.Oct */
+.sb { color: #d01040 } /* Literal.String.Backtick */
+.sc { color: #d01040 } /* Literal.String.Char */
+.sd { color: #d01040 } /* Literal.String.Doc */
+.s2 { color: #d01040 } /* Literal.String.Double */
+.se { color: #d01040 } /* Literal.String.Escape */
+.sh { color: #d01040 } /* Literal.String.Heredoc */
+.si { color: #d01040 } /* Literal.String.Interpol */
+.sx { color: #d01040 } /* Literal.String.Other */
+.sr { color: #009926 } /* Literal.String.Regex */
+.s1 { color: #d01040 } /* Literal.String.Single */
+.ss { color: #990073 } /* Literal.String.Symbol */
+.bp { color: #999999 } /* Name.Builtin.Pseudo */
+.vc { color: #008080 } /* Name.Variable.Class */
+.vg { color: #008080 } /* Name.Variable.Global */
+.vi { color: #008080 } /* Name.Variable.Instance */
+.il { color: #009999 } /* Literal.Number.Integer.Long */
diff --git a/static/css/lib/highlight.css b/static/css/lib/highlight.css
new file mode 100644
index 0000000..f82e1ca
--- /dev/null
+++ b/static/css/lib/highlight.css
@@ -0,0 +1,64 @@
+td.linenos { background-color: #f0f0f0; padding-right: 10px; }
+span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
+pre { line-height: 125% }
+.highlighttable { background-color: #49483e; width: inherit; height: inherit; }
+.hll { display: block }
+ { background: #272822; color: #f8f8f2 }
+.c { color: #75715e } /* Comment */
+.err { color: #960050; background-color: #1e0010 } /* Error */
+.k { color: #66d9ef } /* Keyword */
+.l { color: #ae81ff } /* Literal */
+.n { color: #f8f8f2 } /* Name */
+.o { color: #f92672 } /* Operator */
+.p { color: #f8f8f2 } /* Punctuation */
+.cm { color: #75715e } /* Comment.Multiline */
+.cp { color: #75715e } /* Comment.Preproc */
+.c1 { color: #75715e } /* Comment.Single */
+.cs { color: #75715e } /* Comment.Special */
+.ge { font-style: italic } /* Generic.Emph */
+.gs { font-weight: bold } /* Generic.Strong */
+.kc { color: #66d9ef } /* Keyword.Constant */
+.kd { color: #66d9ef } /* Keyword.Declaration */
+.kn { color: #f92672 } /* Keyword.Namespace */
+.kp { color: #66d9ef } /* Keyword.Pseudo */
+.kr { color: #66d9ef } /* Keyword.Reserved */
+.kt { color: #66d9ef } /* Keyword.Type */
+.ld { color: #e6db74 } /* Literal.Date */
+.m { color: #ae81ff } /* Literal.Number */
+.s { color: #e6db74 } /* Literal.String */
+.na { color: #a6e22e } /* Name.Attribute */
+.nb { color: #f8f8f2 } /* Name.Builtin */
+.nc { color: #a6e22e } /* Name.Class */
+.no { color: #66d9ef } /* Name.Constant */
+.nd { color: #a6e22e } /* Name.Decorator */
+.ni { color: #f8f8f2 } /* Name.Entity */
+.ne { color: #a6e22e } /* Name.Exception */
+.nf { color: #a6e22e } /* Name.Function */
+.nl { color: #f8f8f2 } /* Name.Label */
+.nn { color: #f8f8f2 } /* Name.Namespace */
+.nx { color: #a6e22e } /* Name.Other */
+.py { color: #f8f8f2 } /* Name.Property */
+.nt { color: #f92672 } /* Name.Tag */
+.nv { color: #f8f8f2 } /* Name.Variable */
+.ow { color: #f92672 } /* Operator.Word */
+.w { color: #f8f8f2 } /* Text.Whitespace */
+.mf { color: #ae81ff } /* Literal.Number.Float */
+.mh { color: #ae81ff } /* Literal.Number.Hex */
+.mi { color: #ae81ff } /* Literal.Number.Integer */
+.mo { color: #ae81ff } /* Literal.Number.Oct */
+.sb { color: #e6db74 } /* Literal.String.Backtick */
+.sc { color: #e6db74 } /* Literal.String.Char */
+.sd { color: #e6db74 } /* Literal.String.Doc */
+.s2 { color: #e6db74 } /* Literal.String.Double */
+.se { color: #ae81ff } /* Literal.String.Escape */
+.sh { color: #e6db74 } /* Literal.String.Heredoc */
+.si { color: #e6db74 } /* Literal.String.Interpol */
+.sx { color: #e6db74 } /* Literal.String.Other */
+.sr { color: #e6db74 } /* Literal.String.Regex */
+.s1 { color: #e6db74 } /* Literal.String.Single */
+.ss { color: #e6db74 } /* Literal.String.Symbol */
+.bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
+.vc { color: #f8f8f2 } /* Name.Variable.Class */
+.vg { color: #f8f8f2 } /* Name.Variable.Global */
+.vi { color: #f8f8f2 } /* Name.Variable.Instance */
+.il { color: #ae81ff } /* Literal.Number.Integer.Long */
diff --git a/static/js/index.advanced-search-form.js b/static/js/index.advanced-search-form.js
index 79deb8d..9209a95 100644
--- a/static/js/index.advanced-search-form.js
+++ b/static/js/index.advanced-search-form.js
@@ -37,6 +37,8 @@ var searchGroups = $("div#search-groups");
searchGroups.append(
searchGroup.append(createSearchGroupInput("language")));
$("div#sidebar input[type=checkbox]#language").prop("checked", true);
+
+ searchGroups[0].scrollTop = searchGroups[0].scrollHeight;
});
// Remove the currently selected group if it's not the only one, and mark
@@ -67,7 +69,7 @@ var searchGroups = $("div#search-groups");
})
});
- // Add an input field to the currently selected search group.
+ // Toggle the presence of an input field.
$("div#sidebar input[type=checkbox]").click(function(){
var fieldId = $(this).prop("id");
if($(this).is(":checked")){
@@ -76,8 +78,13 @@ var searchGroups = $("div#search-groups");
if(fieldId.slice(0, 4) == "date")
$(".search-group#selected ." + fieldId).datepicker();
}
- else
- $("div.search-group#selected #" + fieldId).remove()
+ else {
+ if($(".search-group#selected").children("div").length > 1)
+ $(".search-group#selected #" + fieldId).remove()
+ else
+ $(this).prop("checked", true);
+ }
+ searchGroups[0].scrollTop = searchGroups[0].scrollHeight;
});
var previousAdvancedQuery = "";
@@ -125,7 +132,8 @@ function assembleQuery(){
groupQuery.push(genFieldQueryString(
inputFields[field], regexCheckbox[field].checked));
- groupQueries.push(groupQuery.join(" AND "));
+ if(groupQuery.length > 0)
+ groupQueries.push(groupQuery.join(" AND "));
}
return groupQueries.join(" OR ");
@@ -140,8 +148,5 @@ function assembleQuery(){
function genFieldQueryString(field, hasRegex){
var terms = field.value.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"");
var query = field.getAttribute("name") + ":" + (hasRegex?"re:":"") + terms;
- if(field.value.indexOf('"') >= 0){
- return '"' + query + '"';
- }
- return query;
+ return '"' + query + '"';
}
diff --git a/static/js/index.js b/static/js/index.js
index e5a4e14..c49794c 100644
--- a/static/js/index.js
+++ b/static/js/index.js
@@ -5,34 +5,145 @@
var advancedSearchDiv = $("div#advanced-search");
var advancedSearchButton = $("button#advanced-search");
-advancedSearchButton.click(function(){
- var searchField = $("div#search-field");
- if(!advancedSearchDiv.hasClass("visible")){
- searchField.addClass("partly-visible");
- advancedSearchDiv.fadeIn(500).addClass("visible");
- advancedSearchButton.addClass("clicked");
- }
- else {
- advancedSearchDiv.fadeOut(300).removeClass("visible");
- advancedSearchButton.removeClass("clicked");
- if($("div#results .result").length == 0)
- searchField.removeClass("partly-visible");
+FINISH_TYPING_INTERVAL = 650;
+var searchBar = $("form#search-bar input[type='text']")[0];
+var resultsDiv = $("div#results")[0];
+
+var typingTimer, scrollTimer, lastValue;
+var searchResultsPage = 1;
+
+/*
+ * Set all page callbacks.
+ */
+(function setHomePageCallbabacks(){
+ var results = $('#results').get(0);
+
+ // Enable infinite scrolling down the results page.
+ $(window).scroll(function(){
+ if($(window).scrollTop() + $(window).height() == $(document).height() &&
+ resultsDiv.querySelectorAll(".result").length > 0)
+ loadMoreResults();
+
+ clearTimeout(scrollTimer);
+ if (!results.classList.contains('disable-hover'))
+ results.classList.add('disable-hover')
+
+ scrollTimer = setTimeout(function(){
+ if (results.classList.contains('disable-hover'))
+ results.classList.remove('disable-hover');
+ }, 200);
+ });
+
+ // Toggle the advanced-search form's visibility.
+ advancedSearchButton.click(function(){
+ var searchField = $("div#search-field");
+ if(!advancedSearchDiv.hasClass("visible")){
+ searchField.addClass("partly-visible");
+ advancedSearchDiv.fadeIn(500).addClass("visible");
+ advancedSearchButton.addClass("clicked");
+ }
+ else {
+ advancedSearchDiv.fadeOut(300).removeClass("visible");
+ advancedSearchButton.removeClass("clicked");
+ if($("div#results .result").length == 0)
+ searchField.removeClass("partly-visible");
+ }
+ });
+
+ // Enable capturing the `enter` key.
+ $("form#search-bar").submit(function(event){
+ event.preventDefault();
+ return false;
+ });
+ searchBar.onkeyup = typingTimer;
+}());
+
+/*
+ * Set keyboard shortcut mappings.
+ */
+(function resultsHotkeys(){
+ /*
+ * If the currently viewed result is not the first, scroll to the previous
+ * result.
+ */
+ var previousResult = function(){
+ var currResult = $(".display-all");
+ if(currResult.length) {
+ currResult.removeClass("display-all");
+ currResult = currResult.closest(".result").prev(".result");
+ } else {
+ currResult = $(document.querySelectorAll(".result")[0]);
+ }
+
+ currResult.addClass("display-all");
+ currResult.each(function(){
+ $('html,body').stop().animate({
+ scrollTop: $(this).offset().top - (
+ $(window).height() - $(this).outerHeight(true)) / 2
+ }, 140);
+ });
+ };
+
+ /*
+ * If the currently viewed result is not the last, scroll to the next
+ * result.
+ */
+ var nextResult = function(){
+ var currResult = $(".display-all");
+ if(currResult.length) {
+ currResult.removeClass("display-all");
+ currResult = currResult.closest(".result").next(".result");
+ } else {
+ currResult = $(document.querySelectorAll(".result")[0]);
+ }
+
+ currResult.addClass('display-all');
+ currResult.each(function(){
+ $('html,body').stop().animate({
+ scrollTop: $(this).offset().top - (
+ $(window).height() - $(this).outerHeight(true)) / 2
+ }, 140);
+ });
+ };
+
+ var displayHotkeyHelp = function(){
+ var help = $("div#hotkey-help");
+ console.log("H");
+ if(help.hasClass("hidden"))
+ help.fadeIn(420);
+ else
+ help.fadeOut(420);
+
+ $("div#body").toggleClass("faded");
+ help.toggleClass("hidden");
}
-});
-FINISH_TYPING_INTERVAL = 650;
-searchBar = $("form#search-bar input[type='text']")[0];
-resultsDiv = $("div#results")[0];
+ var hotkeyActions = {
+ "k" : previousResult,
+ "j" : nextResult,
+ "h" : previousSymbolMatch,
+ "l" : nextSymbolMatch,
+ "?" : displayHotkeyHelp
+ };
+
+ $(window).keypress(function(key){
+ for(var hotkey in hotkeyActions){
+ var keyChar = String.fromCharCode(key.keyCode);
+ if(keyChar == hotkey &&
+ !($(key.target).is("textarea") || $(key.target).is("input")))
+ hotkeyActions[keyChar]();
+ }
+ });
+}());
-var typingTimer, lastValue;
//Obtained by parsing python file with pygments
-var codeExample = '
1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40 | """\nModule to contain all the project's Flask server plumbing.\n"""\n\nfrom flask import Flask\nfrom flask import render_template, session\n\nfrom bitshift import assets\n# from bitshift.database import Database\n# from bitshift.query import parse_query\n\napp = Flask(__name__)\napp.config.from_object("bitshift.config")\n\napp_env = app.jinja_env\napp_env.line_statement_prefix = "="\napp_env.globals.update(assets=assets)\n\n# database = Database()\n\n@app.route("/")\ndef index():\n return render_template("index.html")\n\n@app.route("/search/<query>")\ndef search(query):\n # tree = parse_query(query)\n # database.search(tree)\n pass\n\n@app.route("/about")\ndef about():\n return render_template("about.html")\n\n@app.route("/developers")\ndef developers():\n return render_template("developers.html")\n\nif __name__ == "__main__":\n app.run(debug=True)\n \n |
'
+var codeExample = ' 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30\n31\n32\n33\n34\n35\n36\n37\n38\n39\n40 | """\nModule to contain all the project's Flask server plumbing.\n"""\n\nfrom flask import Flask\nfrom flask import render_template, session\n\nfrom bitshift import assets\n# from bitshift.database import Database\n# from bitshift.query import parse_query\n\napp = Flask(__name__)\napp.config.from_object("bitshift.config")\n\napp_env = app.jinja_env\napp_env.line_statement_prefix = "="\napp_env.globals.update(assets=assets)\n\n# database = Database()\n\n@app.route("/")\ndef index():\n return render_template("index.html")\n\n@app.route("/search/<query>")\ndef search(query):\n # tree = parse_query(query)\n # database.search(tree)\n pass\n\n@app.route("/about")\ndef about():\n return render_template("about.html")\n\n@app.route("/developers")\ndef developers():\n return render_template("developers.html")\n\nif __name__ == "__main__":\n app.run(debug=True)\n \n |
'
searchBar.onkeyup = typingTimer;
var testCodelet = {
'url': 'https://github.com/earwig/bitshift/blob/develop/app.py',
'filename': 'app.py',
- 'language': 'Python',
+ 'language': 'python',
'date_created': 'May 10, 2014',
'date_modified': '2 days ago',
'origin': ['GitHub', 'https://github.com', ''],
@@ -43,17 +154,12 @@ var testCodelet = {
// Enable infinite scrolling down the results page.
$(window).scroll(function() {
var searchField = $("div#search-field");
- if($(window).scrollTop() + $(window).height() == $(document).height() && searchField.hasClass('partly-visible')){
+ if($(window).scrollTop() + $(window).height() == $(document).height() &&
+ searchField.hasClass('partly-visible')){
loadMoreResults();
}
});
-// Enable capturing the `enter` key.
-$("form#search-bar").submit(function(event){
- event.preventDefault();
- return false;
-});
-
/*
* Clear the existing timer and set a new one the the user types text into the
* search bar.
@@ -109,6 +215,7 @@ function clearResults(){
* with its response.
*/
function populateResults(){
+ searchResultsPage = 1;
var results = queryServer();
for(var result = 0; result < results.length; result++){
@@ -135,74 +242,108 @@ function createResult(codelet) {
row = document.createElement("tr");
//Level 2
var displayInfo = document.createElement("div"),
- sidebar = document.createElement("td"),
codeElt = document.createElement("td"),
- displayButton = document.createElement("td"),
hiddenInfoContainer = document.createElement("td"),
- hiddenInfo = document.createElement("div");
+ hiddenInfo = document.createElement("div"),
+ cycle = document.createElement("div");
//Level 3
var title = document.createElement("span"),
site = document.createElement("span"),
- dateModified = document.createElement("span"),
- language = document.createElement("span"),
- dateCreated = document.createElement("span"),
+ nextMatch = document.createElement("a"),
+ prevMatch = document.createElement("a"),
+ dateModified = document.createElement("div"),
+ language = document.createElement("div"),
+ dateCreated = document.createElement("div"),
authors = document.createElement("div");
//Classes and ID's
newDiv.classList.add('result');
displayInfo.id = 'display-info';
- sidebar.id = 'sidebar';
codeElt.id = 'code';
- displayButton.id = 'display-button';
hiddenInfo.id = 'hidden-info';
+ cycle.id = 'cycle-matches'
title.id = 'title';
site.id = 'site';
+ nextMatch.id = 'next-match';
+ nextMatch.href = '#';
+ prevMatch.id = 'prev-match';
+ prevMatch.href = '#';
dateModified.id = 'date-modified';
language.id = 'language';
dateCreated.id = 'date-created';
authors.id = 'authors';
//Add the bulk of the html
- title.innerHTML = 'File '
+ title.innerHTML = ' » '
+ codelet.filename + '';
- site.innerHTML = 'on ' + codelet.origin[0] +'';
- dateModified.innerHTML = 'Last modified ' + codelet.date_modified;
+ site.innerHTML = '' + codelet.origin[0] +'';
+ nextMatch.innerHTML = 'next match';
+ prevMatch.innerHTML = 'prev match';
+ language.innerHTML = 'Language: ' + codelet.language + '';
+ dateModified.innerHTML = 'Last modified: ' + codelet.date_modified + '';
// Needs to be changed from int to string on the server
- language.innerHTML = codelet.language;
- dateCreated.innerHTML = 'Created ' + codelet.date_created;
- authors.innerHTML = 'Authors: ';
- $.each(codelet.authors, function(i, a) {
- authors.innerHTML += '' + a + ' ';
+ dateCreated.innerHTML = 'Created: ' + codelet.date_created + '';
+
+ var authorsHtml = 'Authors: ';
+ codelet.authors.forEach(function(a, i) {
+ if (i == codelet.authors.length - 1)
+ authorsHtml += '' + a + ' ';
+ else
+ authorsHtml += '' + a + ' , ';
});
+ authors.innerHTML = authorsHtml;
- sidebar.innerHTML = '';
// Needs to be processed on the server
codeElt.innerHTML = '' + codelet.html_code + '
';
//Event binding
- $(displayButton).click(function(e) {
- $(hiddenInfo).toggleClass('visible');
- $(this).toggleClass('active');
+ $(newDiv).on('mousemove', function(e) {
+ var holdCondition = $('.disable-hover');
+
+ if(holdCondition.length == 0) {
+ $(this).siblings().removeClass('display-all');
+ $(this).addClass('display-all');
+ }
+ });
+
+ $(newDiv).on('mouseleave', function(e) {
+ var holdCondition = $('.disable-hover');
+
+ if(holdCondition.length == 0)
+ $(this).removeClass('display-all');
+ });
+
+ $(nextMatch).click(function(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ nextSymbolMatch();
+ });
+
+ $(prevMatch).click(function(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ previousSymbolMatch();
});
//Finish and append elements to parent elements
hiddenInfo.appendChild(dateCreated);
hiddenInfo.appendChild(dateModified);
- hiddenInfo.appendChild(authors);
hiddenInfo.appendChild(language);
+ hiddenInfo.appendChild(authors);
hiddenInfoContainer.appendChild(hiddenInfo);
- row.appendChild(sidebar);
row.appendChild(codeElt);
row.appendChild(hiddenInfoContainer);
- row.appendChild(displayButton);
table.appendChild(row);
- displayInfo.appendChild(title);
displayInfo.appendChild(site);
+ displayInfo.appendChild(title);
+
+ cycle.appendChild(prevMatch);
+ cycle.appendChild(nextMatch);
newDiv.appendChild(displayInfo);
newDiv.appendChild(table);
@@ -210,6 +351,52 @@ function createResult(codelet) {
return newDiv;
}
+function previousSymbolMatch() {
+ var currResult = $(".display-all"),
+ currMatch = currResult.find(".hll.current"),
+ matches = currResult.find(".hll"),
+ scrollDiv = currResult.find("#tablecontainer");
+
+ if (currMatch.length == 0)
+ currMatch = matches[0];
+ else
+ currMatch.removeClass('current');
+
+ var index = matches.index(currMatch.get(0)) - 1;
+ index = index <= 0 ? matches.length - 1 : index;
+ var newMatch = $(matches[index]);
+
+ scrollDiv.scrollTop(scrollDiv.scrollTop()
+ - scrollDiv.height() / 2
+ + newMatch.position().top + newMatch.height() / 2);
+
+ newMatch.effect("highlight", {color: '#FFF'}, 750)
+ newMatch.addClass('current');
+};
+
+function nextSymbolMatch() {
+ var currResult = $(".display-all"),
+ currMatch = currResult.find(".hll.current"),
+ matches = currResult.find(".hll"),
+ scrollDiv = currResult.find("#tablecontainer");
+
+ if (currMatch.length == 0)
+ currMatch = $(matches[0]);
+ else
+ currMatch.removeClass("current");
+
+ var index = matches.index(currMatch.get(0)) + 1;
+ index = index >= matches.length ? 0 : index;
+ var newMatch = $(matches[index]);
+
+ scrollDiv.scrollTop(scrollDiv.scrollTop()
+ - scrollDiv.height() / 2
+ + newMatch.position().top + newMatch.height() / 2);
+
+ newMatch.effect("highlight", {color: "#FFF"}, 750)
+ newMatch.addClass("current");
+};
+
/*
* AJAX the current query string to the server, and return its response.
*
@@ -217,10 +404,23 @@ function createResult(codelet) {
* elements, to fill `div#results`.
*/
function queryServer(){
- var resultDivs = []
+ var queryUrl = document.URL + "search.json?" + $.param({
+ "q" : searchBar.value,
+ "p" : searchResultsPage++
+ });
+
+ var resultDivs = [];
+ $.getJSON(queryUrl, function(result){
+ if("error" in result)
+ insertErrorMessage(result["error"]);
+ else
+ for(var codelet = 0; codelet < result["results"].length; codelet++)
+ resultDivs.push(result["results"][codelet]);
+ });
+
for(var result = 0; result < 20; result++){
var newDiv = createResult(testCodelet);
- resultDivs.push(newDiv);
+ resultDivs.push(newDiv)
}
return resultDivs;
@@ -230,7 +430,7 @@ function queryServer(){
* Adds more results to `div#results`.
*/
function loadMoreResults(){
- results = queryServer();
+ var results = queryServer();
for(var result = 0; result < results.length; result++){
var newDiv = results[result];
resultsDiv.appendChild(newDiv);
@@ -243,3 +443,16 @@ function loadMoreResults(){
result * 20);
}
}
+
+/*
+ * Displays a warning message in the UI.
+ *
+ * @param msg (str) The message string.
+ */
+function insertErrorMessage(msg){
+ var error = $("Error:
");
+ error.append(msg);
+ resultsDiv.appendChild(error[0]);
+}
+
+// loadMoreResults();
diff --git a/static/js/lib/typeahead.bundle.min.js b/static/js/lib/typeahead.bundle.min.js
deleted file mode 100644
index dff8ef5..0000000
--- a/static/js/lib/typeahead.bundle.min.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/*!
- * typeahead.js 0.10.2
- * https://github.com/twitter/typeahead.js
- * Copyright 2013-2014 Twitter, Inc. and other contributors; Licensed MIT
- */
-
-!function(a){var b={isMsie:function(){return/(msie|trident)/i.test(navigator.userAgent)?navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2]:!1},isBlankString:function(a){return!a||/^\s*$/.test(a)},escapeRegExChars:function(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isString:function(a){return"string"==typeof a},isNumber:function(a){return"number"==typeof a},isArray:a.isArray,isFunction:a.isFunction,isObject:a.isPlainObject,isUndefined:function(a){return"undefined"==typeof a},bind:a.proxy,each:function(b,c){function d(a,b){return c(b,a)}a.each(b,d)},map:a.map,filter:a.grep,every:function(b,c){var d=!0;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?void 0:!1}),!!d):d},some:function(b,c){var d=!1;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?!1:void 0}),!!d):d},mixin:a.extend,getUniqueId:function(){var a=0;return function(){return a++}}(),templatify:function(b){function c(){return String(b)}return a.isFunction(b)?b:c},defer:function(a){setTimeout(a,0)},debounce:function(a,b,c){var d,e;return function(){var f,g,h=this,i=arguments;return f=function(){d=null,c||(e=a.apply(h,i))},g=c&&!d,clearTimeout(d),d=setTimeout(f,b),g&&(e=a.apply(h,i)),e}},throttle:function(a,b){var c,d,e,f,g,h;return g=0,h=function(){g=new Date,e=null,f=a.apply(c,d)},function(){var i=new Date,j=b-(i-g);return c=this,d=arguments,0>=j?(clearTimeout(e),e=null,g=i,f=a.apply(c,d)):e||(e=setTimeout(h,j)),f}},noop:function(){}},c="0.10.2",d=function(){function a(a){return a.split(/\s+/)}function b(a){return a.split(/\W+/)}function c(a){return function(b){return function(c){return a(c[b])}}}return{nonword:b,whitespace:a,obj:{nonword:c(b),whitespace:c(a)}}}(),e=function(){function a(a){this.maxSize=a||100,this.size=0,this.hash={},this.list=new c}function c(){this.head=this.tail=null}function d(a,b){this.key=a,this.val=b,this.prev=this.next=null}return b.mixin(a.prototype,{set:function(a,b){var c,e=this.list.tail;this.size>=this.maxSize&&(this.list.remove(e),delete this.hash[e.key]),(c=this.hash[a])?(c.val=b,this.list.moveToFront(c)):(c=new d(a,b),this.list.add(c),this.hash[a]=c,this.size++)},get:function(a){var b=this.hash[a];return b?(this.list.moveToFront(b),b.val):void 0}}),b.mixin(c.prototype,{add:function(a){this.head&&(a.next=this.head,this.head.prev=a),this.head=a,this.tail=this.tail||a},remove:function(a){a.prev?a.prev.next=a.next:this.head=a.next,a.next?a.next.prev=a.prev:this.tail=a.prev},moveToFront:function(a){this.remove(a),this.add(a)}}),a}(),f=function(){function a(a){this.prefix=["__",a,"__"].join(""),this.ttlKey="__ttl__",this.keyMatcher=new RegExp("^"+this.prefix)}function c(){return(new Date).getTime()}function d(a){return JSON.stringify(b.isUndefined(a)?null:a)}function e(a){return JSON.parse(a)}var f,g;try{f=window.localStorage,f.setItem("~~~","!"),f.removeItem("~~~")}catch(h){f=null}return g=f&&window.JSON?{_prefix:function(a){return this.prefix+a},_ttlKey:function(a){return this._prefix(a)+this.ttlKey},get:function(a){return this.isExpired(a)&&this.remove(a),e(f.getItem(this._prefix(a)))},set:function(a,e,g){return b.isNumber(g)?f.setItem(this._ttlKey(a),d(c()+g)):f.removeItem(this._ttlKey(a)),f.setItem(this._prefix(a),d(e))},remove:function(a){return f.removeItem(this._ttlKey(a)),f.removeItem(this._prefix(a)),this},clear:function(){var a,b,c=[],d=f.length;for(a=0;d>a;a++)(b=f.key(a)).match(this.keyMatcher)&&c.push(b.replace(this.keyMatcher,""));for(a=c.length;a--;)this.remove(c[a]);return this},isExpired:function(a){var d=e(f.getItem(this._ttlKey(a)));return b.isNumber(d)&&c()>d?!0:!1}}:{get:b.noop,set:b.noop,remove:b.noop,clear:b.noop,isExpired:b.noop},b.mixin(a.prototype,g),a}(),g=function(){function c(b){b=b||{},this._send=b.transport?d(b.transport):a.ajax,this._get=b.rateLimiter?b.rateLimiter(this._get):this._get}function d(c){return function(d,e){function f(a){b.defer(function(){h.resolve(a)})}function g(a){b.defer(function(){h.reject(a)})}var h=a.Deferred();return c(d,e,f,g),h}}var f=0,g={},h=6,i=new e(10);return c.setMaxPendingRequests=function(a){h=a},c.resetCache=function(){i=new e(10)},b.mixin(c.prototype,{_get:function(a,b,c){function d(b){c&&c(null,b),i.set(a,b)}function e(){c&&c(!0)}function j(){f--,delete g[a],l.onDeckRequestArgs&&(l._get.apply(l,l.onDeckRequestArgs),l.onDeckRequestArgs=null)}var k,l=this;(k=g[a])?k.done(d).fail(e):h>f?(f++,g[a]=this._send(a,b).done(d).fail(e).always(j)):this.onDeckRequestArgs=[].slice.call(arguments,0)},get:function(a,c,d){var e;return b.isFunction(c)&&(d=c,c={}),(e=i.get(a))?b.defer(function(){d&&d(null,e)}):this._get(a,c,d),!!e}}),c}(),h=function(){function c(b){b=b||{},b.datumTokenizer&&b.queryTokenizer||a.error("datumTokenizer and queryTokenizer are both required"),this.datumTokenizer=b.datumTokenizer,this.queryTokenizer=b.queryTokenizer,this.reset()}function d(a){return a=b.filter(a,function(a){return!!a}),a=b.map(a,function(a){return a.toLowerCase()})}function e(){return{ids:[],children:{}}}function f(a){for(var b={},c=[],d=0;db[e]?e++:(f.push(a[d]),d++,e++);return f}return b.mixin(c.prototype,{bootstrap:function(a){this.datums=a.datums,this.trie=a.trie},add:function(a){var c=this;a=b.isArray(a)?a:[a],b.each(a,function(a){var f,g;f=c.datums.push(a)-1,g=d(c.datumTokenizer(a)),b.each(g,function(a){var b,d,g;for(b=c.trie,d=a.split("");g=d.shift();)b=b.children[g]||(b.children[g]=e()),b.ids.push(f)})})},get:function(a){var c,e,h=this;return c=d(this.queryTokenizer(a)),b.each(c,function(a){var b,c,d,f;if(e&&0===e.length)return!1;for(b=h.trie,c=a.split("");b&&(d=c.shift());)b=b.children[d];return b&&0===c.length?(f=b.ids.slice(0),void(e=e?g(e,f):f)):(e=[],!1)}),e?b.map(f(e),function(a){return h.datums[a]}):[]},reset:function(){this.datums=[],this.trie=e()},serialize:function(){return{datums:this.datums,trie:this.trie}}}),c}(),i=function(){function d(a){return a.local||null}function e(d){var e,f;return f={url:null,thumbprint:"",ttl:864e5,filter:null,ajax:{}},(e=d.prefetch||null)&&(e=b.isString(e)?{url:e}:e,e=b.mixin(f,e),e.thumbprint=c+e.thumbprint,e.ajax.type=e.ajax.type||"GET",e.ajax.dataType=e.ajax.dataType||"json",!e.url&&a.error("prefetch requires url to be set")),e}function f(c){function d(a){return function(c){return b.debounce(c,a)}}function e(a){return function(c){return b.throttle(c,a)}}var f,g;return g={url:null,wildcard:"%QUERY",replace:null,rateLimitBy:"debounce",rateLimitWait:300,send:null,filter:null,ajax:{}},(f=c.remote||null)&&(f=b.isString(f)?{url:f}:f,f=b.mixin(g,f),f.rateLimiter=/^throttle$/i.test(f.rateLimitBy)?e(f.rateLimitWait):d(f.rateLimitWait),f.ajax.type=f.ajax.type||"GET",f.ajax.dataType=f.ajax.dataType||"json",delete f.rateLimitBy,delete f.rateLimitWait,!f.url&&a.error("remote requires url to be set")),f}return{local:d,prefetch:e,remote:f}}();!function(c){function e(b){b&&(b.local||b.prefetch||b.remote)||a.error("one of local, prefetch, or remote is required"),this.limit=b.limit||5,this.sorter=j(b.sorter),this.dupDetector=b.dupDetector||k,this.local=i.local(b),this.prefetch=i.prefetch(b),this.remote=i.remote(b),this.cacheKey=this.prefetch?this.prefetch.cacheKey||this.prefetch.url:null,this.index=new h({datumTokenizer:b.datumTokenizer,queryTokenizer:b.queryTokenizer}),this.storage=this.cacheKey?new f(this.cacheKey):null}function j(a){function c(b){return b.sort(a)}function d(a){return a}return b.isFunction(a)?c:d}function k(){return!1}var l,m;return l=c.Bloodhound,m={data:"data",protocol:"protocol",thumbprint:"thumbprint"},c.Bloodhound=e,e.noConflict=function(){return c.Bloodhound=l,e},e.tokenizers=d,b.mixin(e.prototype,{_loadPrefetch:function(b){function c(a){f.clear(),f.add(b.filter?b.filter(a):a),f._saveToStorage(f.index.serialize(),b.thumbprint,b.ttl)}var d,e,f=this;return(d=this._readFromStorage(b.thumbprint))?(this.index.bootstrap(d),e=a.Deferred().resolve()):e=a.ajax(b.url,b.ajax).done(c),e},_getFromRemote:function(a,b){function c(a,c){b(a?[]:f.remote.filter?f.remote.filter(c):c)}var d,e,f=this;return a=a||"",e=encodeURIComponent(a),d=this.remote.replace?this.remote.replace(this.remote.url,a):this.remote.url.replace(this.remote.wildcard,e),this.transport.get(d,this.remote.ajax,c)},_saveToStorage:function(a,b,c){this.storage&&(this.storage.set(m.data,a,c),this.storage.set(m.protocol,location.protocol,c),this.storage.set(m.thumbprint,b,c))},_readFromStorage:function(a){var b,c={};return this.storage&&(c.data=this.storage.get(m.data),c.protocol=this.storage.get(m.protocol),c.thumbprint=this.storage.get(m.thumbprint)),b=c.thumbprint!==a||c.protocol!==location.protocol,c.data&&!b?c.data:null},_initialize:function(){function c(){e.add(b.isFunction(f)?f():f)}var d,e=this,f=this.local;return d=this.prefetch?this._loadPrefetch(this.prefetch):a.Deferred().resolve(),f&&d.done(c),this.transport=this.remote?new g(this.remote):null,this.initPromise=d.promise()},initialize:function(a){return!this.initPromise||a?this._initialize():this.initPromise},add:function(a){this.index.add(a)},get:function(a,c){function d(a){var d=f.slice(0);b.each(a,function(a){var c;return c=b.some(d,function(b){return e.dupDetector(a,b)}),!c&&d.push(a),d.length0||!this.transport)&&c&&c(f)},clear:function(){this.index.reset()},clearPrefetchCache:function(){this.storage&&this.storage.clear()},clearRemoteCache:function(){this.transport&&g.resetCache()},ttAdapter:function(){return b.bind(this.get,this)}}),e}(this);var j={wrapper:'',dropdown:'',dataset:'',suggestions:'',suggestion:''},k={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none"},input:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},inputWithNoHint:{position:"relative",verticalAlign:"top"},dropdown:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"},suggestions:{display:"block"},suggestion:{whiteSpace:"nowrap",cursor:"pointer"},suggestionChild:{whiteSpace:"normal"},ltr:{left:"0",right:"auto"},rtl:{left:"auto",right:" 0"}};b.isMsie()&&b.mixin(k.input,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),b.isMsie()&&b.isMsie()<=7&&b.mixin(k.input,{marginTop:"-1px"});var l=function(){function c(b){b&&b.el||a.error("EventBus initialized without el"),this.$el=a(b.el)}var d="typeahead:";return b.mixin(c.prototype,{trigger:function(a){var b=[].slice.call(arguments,1);this.$el.trigger(d+a,b)}}),c}(),m=function(){function a(a,b,c,d){var e;if(!c)return this;for(b=b.split(i),c=d?h(c,d):c,this._callbacks=this._callbacks||{};e=b.shift();)this._callbacks[e]=this._callbacks[e]||{sync:[],async:[]},this._callbacks[e][a].push(c);return this}function b(b,c,d){return a.call(this,"async",b,c,d)}function c(b,c,d){return a.call(this,"sync",b,c,d)}function d(a){var b;if(!this._callbacks)return this;for(a=a.split(i);b=a.shift();)delete this._callbacks[b];return this}function e(a){var b,c,d,e,g;if(!this._callbacks)return this;for(a=a.split(i),d=[].slice.call(arguments,1);(b=a.shift())&&(c=this._callbacks[b]);)e=f(c.sync,this,[b].concat(d)),g=f(c.async,this,[b].concat(d)),e()&&j(g);return this}function f(a,b,c){function d(){for(var d,e=0;!d&&e').css({position:"absolute",visibility:"hidden",whiteSpace:"pre",fontFamily:b.css("font-family"),fontSize:b.css("font-size"),fontStyle:b.css("font-style"),fontVariant:b.css("font-variant"),fontWeight:b.css("font-weight"),wordSpacing:b.css("word-spacing"),letterSpacing:b.css("letter-spacing"),textIndent:b.css("text-indent"),textRendering:b.css("text-rendering"),textTransform:b.css("text-transform")}).insertAfter(b)}function e(a,b){return c.normalizeQuery(a)===c.normalizeQuery(b)}function f(a){return a.altKey||a.ctrlKey||a.metaKey||a.shiftKey}var g;return g={9:"tab",27:"esc",37:"left",39:"right",13:"enter",38:"up",40:"down"},c.normalizeQuery=function(a){return(a||"").replace(/^\s*/g,"").replace(/\s{2,}/g," ")},b.mixin(c.prototype,m,{_onBlur:function(){this.resetInputValue(),this.trigger("blurred")},_onFocus:function(){this.trigger("focused")},_onKeydown:function(a){var b=g[a.which||a.keyCode];this._managePreventDefault(b,a),b&&this._shouldTrigger(b,a)&&this.trigger(b+"Keyed",a)},_onInput:function(){this._checkInputValue()},_managePreventDefault:function(a,b){var c,d,e;switch(a){case"tab":d=this.getHint(),e=this.getInputValue(),c=d&&d!==e&&!f(b);break;case"up":case"down":c=!f(b);break;default:c=!1}c&&b.preventDefault()},_shouldTrigger:function(a,b){var c;switch(a){case"tab":c=!f(b);break;default:c=!0}return c},_checkInputValue:function(){var a,b,c;a=this.getInputValue(),b=e(a,this.query),c=b?this.query.length!==a.length:!1,b?c&&this.trigger("whitespaceChanged",this.query):this.trigger("queryChanged",this.query=a)},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getQuery:function(){return this.query},setQuery:function(a){this.query=a},getInputValue:function(){return this.$input.val()},setInputValue:function(a,b){this.$input.val(a),b?this.clearHint():this._checkInputValue()},resetInputValue:function(){this.setInputValue(this.query,!0)},getHint:function(){return this.$hint.val()},setHint:function(a){this.$hint.val(a)},clearHint:function(){this.setHint("")},clearHintIfInvalid:function(){var a,b,c,d;a=this.getInputValue(),b=this.getHint(),c=a!==b&&0===b.indexOf(a),d=""!==a&&c&&!this.hasOverflow(),!d&&this.clearHint()},getLanguageDirection:function(){return(this.$input.css("direction")||"ltr").toLowerCase()},hasOverflow:function(){var a=this.$input.width()-2;return this.$overflowHelper.text(this.getInputValue()),this.$overflowHelper.width()>=a},isCursorAtEnd:function(){var a,c,d;return a=this.$input.val().length,c=this.$input[0].selectionStart,b.isNumber(c)?c===a:document.selection?(d=document.selection.createRange(),d.moveStart("character",-a),a===d.text.length):!0},destroy:function(){this.$hint.off(".tt"),this.$input.off(".tt"),this.$hint=this.$input=this.$overflowHelper=null}}),c}(),p=function(){function c(c){c=c||{},c.templates=c.templates||{},c.source||a.error("missing source"),c.name&&!f(c.name)&&a.error("invalid dataset name: "+c.name),this.query=null,this.highlight=!!c.highlight,this.name=c.name||b.getUniqueId(),this.source=c.source,this.displayFn=d(c.display||c.displayKey),this.templates=e(c.templates,this.displayFn),this.$el=a(j.dataset.replace("%CLASS%",this.name))}function d(a){function c(b){return b[a]}return a=a||"value",b.isFunction(a)?a:c}function e(a,c){function d(a){return""+c(a)+"
"}return{empty:a.empty&&b.templatify(a.empty),header:a.header&&b.templatify(a.header),footer:a.footer&&b.templatify(a.footer),suggestion:a.suggestion||d}}function f(a){return/^[_a-zA-Z0-9-]+$/.test(a)}var g="ttDataset",h="ttValue",i="ttDatum";return c.extractDatasetName=function(b){return a(b).data(g)},c.extractValue=function(b){return a(b).data(h)},c.extractDatum=function(b){return a(b).data(i)},b.mixin(c.prototype,m,{_render:function(c,d){function e(){return p.templates.empty({query:c,isEmpty:!0})}function f(){function e(b){var c;return c=a(j.suggestion).append(p.templates.suggestion(b)).data(g,p.name).data(h,p.displayFn(b)).data(i,b),c.children().each(function(){a(this).css(k.suggestionChild)}),c}var f,l;return f=a(j.suggestions).css(k.suggestions),l=b.map(d,e),f.append.apply(f,l),p.highlight&&n({node:f[0],pattern:c}),f}function l(){return p.templates.header({query:c,isEmpty:!o})}function m(){return p.templates.footer({query:c,isEmpty:!o})}if(this.$el){var o,p=this;this.$el.empty(),o=d&&d.length,!o&&this.templates.empty?this.$el.html(e()).prepend(p.templates.header?l():null).append(p.templates.footer?m():null):o&&this.$el.html(f()).prepend(p.templates.header?l():null).append(p.templates.footer?m():null),this.trigger("rendered")}},getRoot:function(){return this.$el},update:function(a){function b(b){c.canceled||a!==c.query||c._render(a,b)}var c=this;this.query=a,this.canceled=!1,this.source(a,b)},cancel:function(){this.canceled=!0},clear:function(){this.cancel(),this.$el.empty(),this.trigger("rendered")},isEmpty:function(){return this.$el.is(":empty")},destroy:function(){this.$el=null}}),c}(),q=function(){function c(c){var e,f,g,h=this;c=c||{},c.menu||a.error("menu is required"),this.isOpen=!1,this.isEmpty=!0,this.datasets=b.map(c.datasets,d),e=b.bind(this._onSuggestionClick,this),f=b.bind(this._onSuggestionMouseEnter,this),g=b.bind(this._onSuggestionMouseLeave,this),this.$menu=a(c.menu).on("click.tt",".tt-suggestion",e).on("mouseenter.tt",".tt-suggestion",f).on("mouseleave.tt",".tt-suggestion",g),b.each(this.datasets,function(a){h.$menu.append(a.getRoot()),a.onSync("rendered",h._onRendered,h)})}function d(a){return new p(a)}return b.mixin(c.prototype,m,{_onSuggestionClick:function(b){this.trigger("suggestionClicked",a(b.currentTarget))},_onSuggestionMouseEnter:function(b){this._removeCursor(),this._setCursor(a(b.currentTarget),!0)},_onSuggestionMouseLeave:function(){this._removeCursor()},_onRendered:function(){function a(a){return a.isEmpty()}this.isEmpty=b.every(this.datasets,a),this.isEmpty?this._hide():this.isOpen&&this._show(),this.trigger("datasetRendered")},_hide:function(){this.$menu.hide()},_show:function(){this.$menu.css("display","block")},_getSuggestions:function(){return this.$menu.find(".tt-suggestion")},_getCursor:function(){return this.$menu.find(".tt-cursor").first()},_setCursor:function(a,b){a.first().addClass("tt-cursor"),!b&&this.trigger("cursorMoved")},_removeCursor:function(){this._getCursor().removeClass("tt-cursor")},_moveCursor:function(a){var b,c,d,e;if(this.isOpen){if(c=this._getCursor(),b=this._getSuggestions(),this._removeCursor(),d=b.index(c)+a,d=(d+1)%(b.length+1)-1,-1===d)return void this.trigger("cursorRemoved");-1>d&&(d=b.length-1),this._setCursor(e=b.eq(d)),this._ensureVisible(e)}},_ensureVisible:function(a){var b,c,d,e;b=a.position().top,c=b+a.outerHeight(!0),d=this.$menu.scrollTop(),e=this.$menu.height()+parseInt(this.$menu.css("paddingTop"),10)+parseInt(this.$menu.css("paddingBottom"),10),0>b?this.$menu.scrollTop(d+b):c>e&&this.$menu.scrollTop(d+(c-e))},close:function(){this.isOpen&&(this.isOpen=!1,this._removeCursor(),this._hide(),this.trigger("closed"))},open:function(){this.isOpen||(this.isOpen=!0,!this.isEmpty&&this._show(),this.trigger("opened"))},setLanguageDirection:function(a){this.$menu.css("ltr"===a?k.ltr:k.rtl)},moveCursorUp:function(){this._moveCursor(-1)},moveCursorDown:function(){this._moveCursor(1)},getDatumForSuggestion:function(a){var b=null;return a.length&&(b={raw:p.extractDatum(a),value:p.extractValue(a),datasetName:p.extractDatasetName(a)}),b},getDatumForCursor:function(){return this.getDatumForSuggestion(this._getCursor().first())},getDatumForTopSuggestion:function(){return this.getDatumForSuggestion(this._getSuggestions().first())},update:function(a){function c(b){b.update(a)}b.each(this.datasets,c)},empty:function(){function a(a){a.clear()}b.each(this.datasets,a),this.isEmpty=!0},isVisible:function(){return this.isOpen&&!this.isEmpty},destroy:function(){function a(a){a.destroy()}this.$menu.off(".tt"),this.$menu=null,b.each(this.datasets,a)}}),c}(),r=function(){function c(c){var e,f,g;c=c||{},c.input||a.error("missing input"),this.isActivated=!1,this.autoselect=!!c.autoselect,this.minLength=b.isNumber(c.minLength)?c.minLength:1,this.$node=d(c.input,c.withHint),e=this.$node.find(".tt-dropdown-menu"),f=this.$node.find(".tt-input"),g=this.$node.find(".tt-hint"),f.on("blur.tt",function(a){var c,d,g;c=document.activeElement,d=e.is(c),g=e.has(c).length>0,b.isMsie()&&(d||g)&&(a.preventDefault(),a.stopImmediatePropagation(),b.defer(function(){f.focus()}))}),e.on("mousedown.tt",function(a){a.preventDefault()}),this.eventBus=c.eventBus||new l({el:f}),this.dropdown=new q({menu:e,datasets:c.datasets}).onSync("suggestionClicked",this._onSuggestionClicked,this).onSync("cursorMoved",this._onCursorMoved,this).onSync("cursorRemoved",this._onCursorRemoved,this).onSync("opened",this._onOpened,this).onSync("closed",this._onClosed,this).onAsync("datasetRendered",this._onDatasetRendered,this),this.input=new o({input:f,hint:g}).onSync("focused",this._onFocused,this).onSync("blurred",this._onBlurred,this).onSync("enterKeyed",this._onEnterKeyed,this).onSync("tabKeyed",this._onTabKeyed,this).onSync("escKeyed",this._onEscKeyed,this).onSync("upKeyed",this._onUpKeyed,this).onSync("downKeyed",this._onDownKeyed,this).onSync("leftKeyed",this._onLeftKeyed,this).onSync("rightKeyed",this._onRightKeyed,this).onSync("queryChanged",this._onQueryChanged,this).onSync("whitespaceChanged",this._onWhitespaceChanged,this),this._setLanguageDirection()}function d(b,c){var d,f,h,i;d=a(b),f=a(j.wrapper).css(k.wrapper),h=a(j.dropdown).css(k.dropdown),i=d.clone().css(k.hint).css(e(d)),i.val("").removeData().addClass("tt-hint").removeAttr("id name placeholder").prop("disabled",!0).attr({autocomplete:"off",spellcheck:"false"}),d.data(g,{dir:d.attr("dir"),autocomplete:d.attr("autocomplete"),spellcheck:d.attr("spellcheck"),style:d.attr("style")}),d.addClass("tt-input").attr({autocomplete:"off",spellcheck:!1}).css(c?k.input:k.inputWithNoHint);try{!d.attr("dir")&&d.attr("dir","auto")}catch(l){}return d.wrap(f).parent().prepend(c?i:null).append(h)}function e(a){return{backgroundAttachment:a.css("background-attachment"),backgroundClip:a.css("background-clip"),backgroundColor:a.css("background-color"),backgroundImage:a.css("background-image"),backgroundOrigin:a.css("background-origin"),backgroundPosition:a.css("background-position"),backgroundRepeat:a.css("background-repeat"),backgroundSize:a.css("background-size")}}function f(a){var c=a.find(".tt-input");b.each(c.data(g),function(a,d){b.isUndefined(a)?c.removeAttr(d):c.attr(d,a)}),c.detach().removeData(g).removeClass("tt-input").insertAfter(a),a.remove()}var g="ttAttrs";return b.mixin(c.prototype,{_onSuggestionClicked:function(a,b){var c;(c=this.dropdown.getDatumForSuggestion(b))&&this._select(c)},_onCursorMoved:function(){var a=this.dropdown.getDatumForCursor();this.input.setInputValue(a.value,!0),this.eventBus.trigger("cursorchanged",a.raw,a.datasetName)},_onCursorRemoved:function(){this.input.resetInputValue(),this._updateHint()},_onDatasetRendered:function(){this._updateHint()},_onOpened:function(){this._updateHint(),this.eventBus.trigger("opened")},_onClosed:function(){this.input.clearHint(),this.eventBus.trigger("closed")},_onFocused:function(){this.isActivated=!0,this.dropdown.open()},_onBlurred:function(){this.isActivated=!1,this.dropdown.empty(),this.dropdown.close()},_onEnterKeyed:function(a,b){var c,d;c=this.dropdown.getDatumForCursor(),d=this.dropdown.getDatumForTopSuggestion(),c?(this._select(c),b.preventDefault()):this.autoselect&&d&&(this._select(d),b.preventDefault())},_onTabKeyed:function(a,b){var c;(c=this.dropdown.getDatumForCursor())?(this._select(c),b.preventDefault()):this._autocomplete(!0)},_onEscKeyed:function(){this.dropdown.close(),this.input.resetInputValue()},_onUpKeyed:function(){var a=this.input.getQuery();this.dropdown.isEmpty&&a.length>=this.minLength?this.dropdown.update(a):this.dropdown.moveCursorUp(),this.dropdown.open()},_onDownKeyed:function(){var a=this.input.getQuery();this.dropdown.isEmpty&&a.length>=this.minLength?this.dropdown.update(a):this.dropdown.moveCursorDown(),this.dropdown.open()},_onLeftKeyed:function(){"rtl"===this.dir&&this._autocomplete()},_onRightKeyed:function(){"ltr"===this.dir&&this._autocomplete()},_onQueryChanged:function(a,b){this.input.clearHintIfInvalid(),b.length>=this.minLength?this.dropdown.update(b):this.dropdown.empty(),this.dropdown.open(),this._setLanguageDirection()},_onWhitespaceChanged:function(){this._updateHint(),this.dropdown.open()},_setLanguageDirection:function(){var a;this.dir!==(a=this.input.getLanguageDirection())&&(this.dir=a,this.$node.css("direction",a),this.dropdown.setLanguageDirection(a))},_updateHint:function(){var a,c,d,e,f,g;a=this.dropdown.getDatumForTopSuggestion(),a&&this.dropdown.isVisible()&&!this.input.hasOverflow()?(c=this.input.getInputValue(),d=o.normalizeQuery(c),e=b.escapeRegExChars(d),f=new RegExp("^(?:"+e+")(.+$)","i"),g=f.exec(a.value),g?this.input.setHint(c+g[1]):this.input.clearHint()):this.input.clearHint()},_autocomplete:function(a){var b,c,d,e;b=this.input.getHint(),c=this.input.getQuery(),d=a||this.input.isCursorAtEnd(),b&&c!==b&&d&&(e=this.dropdown.getDatumForTopSuggestion(),e&&this.input.setInputValue(e.value),this.eventBus.trigger("autocompleted",e.raw,e.datasetName))},_select:function(a){this.input.setQuery(a.value),this.input.setInputValue(a.value,!0),this._setLanguageDirection(),this.eventBus.trigger("selected",a.raw,a.datasetName),this.dropdown.close(),b.defer(b.bind(this.dropdown.empty,this.dropdown))},open:function(){this.dropdown.open()},close:function(){this.dropdown.close()},setVal:function(a){this.isActivated?this.input.setInputValue(a):(this.input.setQuery(a),this.input.setInputValue(a,!0)),this._setLanguageDirection()},getVal:function(){return this.input.getQuery()},destroy:function(){this.input.destroy(),this.dropdown.destroy(),f(this.$node),this.$node=null}}),c}();!function(){var c,d,e;c=a.fn.typeahead,d="ttTypeahead",e={initialize:function(c,e){function f(){var f,g,h=a(this);b.each(e,function(a){a.highlight=!!c.highlight}),g=new r({input:h,eventBus:f=new l({el:h}),withHint:b.isUndefined(c.hint)?!0:!!c.hint,minLength:c.minLength,autoselect:c.autoselect,datasets:e}),h.data(d,g)}return e=b.isArray(e)?e:[].slice.call(arguments,1),c=c||{},this.each(f)},open:function(){function b(){var b,c=a(this);(b=c.data(d))&&b.open()}return this.each(b)},close:function(){function b(){var b,c=a(this);(b=c.data(d))&&b.close()}return this.each(b)},val:function(b){function c(){var c,e=a(this);(c=e.data(d))&&c.setVal(b)}function e(a){var b,c;return(b=a.data(d))&&(c=b.getVal()),c}return arguments.length?this.each(c):e(this.first())},destroy:function(){function b(){var b,c=a(this);(b=c.data(d))&&(b.destroy(),c.removeData(d))}return this.each(b)}},a.fn.typeahead=function(a){return e[a]?e[a].apply(this,[].slice.call(arguments,1)):e.initialize.apply(this,arguments)},a.fn.typeahead.noConflict=function(){return a.fn.typeahead=c,this}}()}(window.jQuery);
\ No newline at end of file
diff --git a/static/sass/_mixins.sass b/static/sass/_mixins.sass
index 379fb2d..10dc4b9 100644
--- a/static/sass/_mixins.sass
+++ b/static/sass/_mixins.sass
@@ -10,6 +10,11 @@
-o-#{$property}: $value
#{$property}: $value
+// Add portable opacity style.
+@mixin opaque($opacity)
+ @include vendor(opacity, $opacity)
+ filter: alpha(opacity=$opacity)
+
.t1
@include vendor(transition, all 0.1s ease-out)
diff --git a/static/sass/index.sass b/static/sass/index.sass
index 300df45..2a90900 100644
--- a/static/sass/index.sass
+++ b/static/sass/index.sass
@@ -6,9 +6,8 @@
@import variables
$minSearchFieldsWidth: 490px
-$resultWidth: 830px
-$sidebarWidth: 30px
-$codeWidth: 500px
+$resultWidth: 1000px
+$codeWidth: 650px
$hiddenInfoWidth: 250px
.ui-datepicker
@@ -23,6 +22,54 @@ $hiddenInfoWidth: 250px
>li.ui-menu-item a.ui-state-focus
@include vendor(transition, background-color 0.3s ease-out)
+div#body
+ @extend .t3
+
+ &.faded
+ @include opaque(0.8)
+
+div#hotkey-help
+ $width: 40%
+
+ background-color: white
+ border: 1px solid $baseColor3
+ left: 50% - $width / 2
+ min-width: 400px
+ padding: 35px
+ position: fixed
+ top: 30%
+ width: $width
+ z-index: 200
+
+ &.hidden
+ display: none
+
+ div
+ border-bottom: 1px solid $baseColor2
+ color: $baseColor1
+ font-size: 130%
+ padding-bottom: 8px
+ text-align: center
+
+ ul
+ list-style: none
+ margin-left: auto
+ margin-right: auto
+ position: relative
+ width: 300px
+
+ li
+ margin-bottom: 4px
+
+ span.hotkey
+ color: $baseColor1
+ font-family: monospace
+ font-size: 130%
+ font-weight: bold
+
+ span.seperator
+ color: $baseColor2
+
div#search-field
@extend .t2
@@ -34,6 +81,7 @@ div#search-field
max-height: 100px
right: 0
position: absolute
+ z-index: 2
top: 0
width: 40%
@@ -103,7 +151,6 @@ div#search-field
&.partly-visible
margin-top: 0%
- padding-bottom: 3%
position: absolute
width: 100%
@@ -121,6 +168,11 @@ div#search-field
margin-right: auto
width: 60%
+ input:hover
+ @extend .t3
+
+ border: 1px solid $baseColor1
+
div#advanced-search
background-color: white
border: 1px solid $baseColor3
@@ -237,7 +289,7 @@ div#advanced-search
#search-groups
margin-top: 1%
- max-height: 93%
+ max-height: 87%
overflow-y: auto
width: 75%
@@ -286,112 +338,116 @@ div#results
margin-right: auto
width: 80%
- /* TODO:
- 1) Sidebar
- - Add way to cycle through hits in the code.
- 2) Hidden info
- - Add links for authors.
- - Remove language field.
- 3) Header
- - Add an icon for the website.
- - Add language tag.
- 4) Code body
- - Add highlighting.*/
- div.result
- width: $resultWidth
- height: 200px
- margin-top: 2%
- margin-bottom: 6%
-
- #display-info
- font-size: 1.2em
-
- a
- text-decoration: none
-
- &:hover
- color: orange
-
- #title
- margin-right: 10px
-
- #site
- text-transform: capitalize
+ a
+ text-decoration: none
+
+ &:hover
+ color: orange
+
+ div#error
+ font-size: 170%
+ margin-top: 22%
+ text-align: center
+
+ span
+ color: $baseColor1
+ font-size: 150%
+
+ &.disable-hover
+ pointer-events: none
+
+div.result
+ @extend .t3
+
+ width: $resultWidth
+ height: 200px
+ margin-bottom: 100%
+ pointer-events: auto
+
+ table
+ border-collapse: collapse
+ height: inherit
+
+ tr
+ @extend .t3
+ @include opaque(0.8)
- table
- border-collapse: collapse
- border: 1px solid $baseColor3
height: inherit
- tr
- height: inherit
-
- #sidebar
- width: $sidebarWidth
- background-color: #eee
- border-right: 1px solid $baseColor3
- height: inherit
-
- #code
- width: $codeWidth
- height: inherit
- border-right: 1px solid $baseColor3
-
- #tablecontainer
- overflow: scroll
- width: 100%
- height: inherit
- background-color: #49483e
-
- table
- table-layout:fixed
- border-collapse: collapse
- border: none
- font-family: monospace
-
- #display-button
- width: 25px
- background: url(http://icons.iconarchive.com/icons/visualpharm/icons8-metro-style/512/Image-Edition-Tools-Arrow-icon.png)
- background-size: 25px 25px
- background-repeat: no-repeat
- background-position: center
+ &.cascade
+ @extend .t1
+ margin-bottom: 15%
- &:hover
- background-color: #eee
+ &.display-all table tr
+ @include opaque(1.0)
- &.active
- @include vendor(transform, rotateY(180deg))
+div#display-info
+ font-size: 1.3em
+ padding: 5px 0px 5px 5px
+ width: 100%
- #hidden-info
- width: $hiddenInfoWidth
- margin-left: -$hiddenInfoWidth
- height: 100%
- padding-top: 50px
- text-align: center
- font-size: 1em
- line-height: 1.5em
- @include vendor(transition, margin-left 0.2s ease-in-out)
+ #title
+ margin-right: 10px
- &.visible
- margin-left: 0px
+ #site
+ text-transform: capitalize
- #date-created
- display: inline-block
+td#code
+ @include vendor(transition, width 0.2s ease-in-out)
- #date-modified
- display: block
+ width: $codeWidth
+ height: inherit
+ padding: 0px
+ border: 1px solid #bbb
- #language
- display: inline-block
- font-weight: bold
- color: orange
+ #tablecontainer
+ overflow: hidden
+ width: 100%
+ height: inherit
+ background-color: #49483e
+ position: relative
+ z-index: 1
- #authors
- a
- text-decoration: none
+ table
+ border-collapse: collapse
+ font-family: monospace
- &:hover
- color: orange
+ .linenos
+ padding-left: 1%
- &.cascade
- @extend .t3
+ pre
+ margin-top: 5px
+
+ .code pre
+ margin-top: 5px
+
+ .hll
+ background: #5B5A51
+
+div#hidden-info
+ width: $hiddenInfoWidth
+ margin-left: -$hiddenInfoWidth - 10px
+ height: 100%
+ padding-top: 40px
+ font-size: 1.2em
+ line-height: 1.5em
+ position: relative
+ z-index: 0
+
+ @include vendor(transition, margin-left 0.2s ease-in-out)
+
+ .display-all &
+ margin-left: 0px
+ padding-left: 20px
+
+ span
+ font-family: monospace
+ color: $baseColor1
+ float: right
+
+ div
+ display: block
+
+ #authors
+ a
+ font-family: monospace
diff --git a/templates/index.html b/templates/index.html
index ec2a493..67ba677 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -1,14 +1,13 @@
= extends "layout.html"
= block title
- Home
+ home
= endblock
= block head
{{ assets.tag("lib/jqueryui.custom.min.css") }}
{{ assets.tag("lib/jquery.min.js") }}
{{ assets.tag("lib/jquery-ui.min.js") }}
- {{ assets.tag("lib/typeahead.bundle.min.js") }}
{{ assets.tag("lib/highlight.css") }}
{{ assets.tag("index.css") }}
@@ -30,7 +29,7 @@