Browse Source

[search] Add front end dependencies to search app

Abraham Elmahrek 12 years ago
parent
commit
75cc0db

+ 1 - 1
apps/search/src/search/templates/admin_collection_facets.mako

@@ -216,7 +216,7 @@ ${ commonheader(_('Search'), "search", user, "40px") | n,unicode }
 <script src="/static/ext/js/bootstrap-datepicker.min.js" type="text/javascript" charset="utf-8"></script>
 <script src="/static/ext/js/bootstrap-editable.min.js"></script>
 <script src="/static/ext/js/moment.min.js" type="text/javascript" charset="utf-8"></script>
-<script src="/static/ext/js/knockout-sortable.min.js" type="text/javascript" charset="utf-8"></script>
+<script src="/search/static/js/knockout-sortable.min.js" type="text/javascript" charset="utf-8"></script>
 <script src="/static/ext/js/jquery/plugins/jquery-ui-draggable-droppable-sortable-1.8.23.min.js"></script>
 
 <script type="text/javascript">

+ 5 - 5
apps/search/src/search/templates/admin_collection_template.mako

@@ -410,14 +410,14 @@ ${ commonheader(_('Search'), "search", user, "40px") | n,unicode }
   ${ hue_collection.result.get_extracode() | n,unicode }
 </span>
 
-<link rel="stylesheet" href="/static/ext/farbtastic/farbtastic.css">
-<link rel="stylesheet" href="/static/ext/css/freshereditor.css">
+<link rel="stylesheet" href="/search/static/farbtastic/farbtastic.css">
+<link rel="stylesheet" href="/search/static/css/freshereditor.css">
 <link rel="stylesheet" href="/static/ext/css/codemirror.css">
 
 <script src="/static/ext/js/knockout-2.1.0.js" type="text/javascript" charset="utf-8"></script>
-<script src="/static/ext/farbtastic/farbtastic.js" type="text/javascript" charset="utf-8"></script>
-<script src="/static/ext/js/shortcut.js" type="text/javascript" charset="utf-8"></script>
-<script src="/static/ext/js/freshereditor.min.js" type="text/javascript" charset="utf-8"></script>
+<script src="/search/static/farbtastic/farbtastic.js" type="text/javascript" charset="utf-8"></script>
+<script src="/search/static/js/shortcut.js" type="text/javascript" charset="utf-8"></script>
+<script src="/search/static/js/freshereditor.min.js" type="text/javascript" charset="utf-8"></script>
 <script src="/static/ext/js/codemirror-3.11.js"></script>
 <script src="/static/ext/js/moment.min.js" type="text/javascript" charset="utf-8"></script>
 <script src="/static/ext/js/codemirror-xml.js"></script>

+ 3 - 3
apps/search/src/search/templates/layout.mako

@@ -22,8 +22,8 @@
 
 <%def name="skeleton()">
   <link rel="stylesheet" href="/search/static/css/admin.css">
-  <link rel="stylesheet" href="/static/ext/chosen/chosen.css">
-  <script src="/static/ext/chosen/chosen.jquery.min.js" type="text/javascript" charset="utf-8"></script>
+  <link rel="stylesheet" href="/search/static/chosen/chosen.css">
+  <script src="/search/static/chosen/chosen.jquery.min.js" type="text/javascript" charset="utf-8"></script>
   <script src="/static/ext/js/knockout-2.1.0.js" type="text/javascript" charset="utf-8"></script>
 
   <div class="search-bar" style="height: 30px">
@@ -100,4 +100,4 @@
 
     </ul>
   </div>
-</%def>
+</%def>

BIN
apps/search/static/chosen/chosen-sprite.png


+ 418 - 0
apps/search/static/chosen/chosen.css

@@ -0,0 +1,418 @@
+/*
+*
+* Chosen for Bootstrap and Less
+*
+* Converted by @whitetruffle (http://www.twitter.com/whitetruffle)
+* from @joeylomanto's SASS fork (http://chosen-sass-bootstrap.herokuapp.com/)
+* Havest: @harvest
+*
+*/
+
+.chzn-container {
+  position: relative;
+  display: inline-block;
+  zoom: 1;
+  *display: inline;
+}
+.chzn-container .chzn-drop {
+  -webkit-border-radius: 4px;
+  -moz-border-radius: 4px;
+  border-radius: 4px;
+  -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
+  -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
+  box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
+  background: #fff;
+  border: 1px solid #CCC;
+  position: absolute;
+  top: 29px;
+  left: 0;
+  z-index: 1010;
+  margin: 4px 0 0;
+}
+.chzn-container-single .chzn-single {
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+  border-radius: 3px;
+  -webkit-box-shadow: 0 0 3px #ffffff inset, 0 1px 1px rgba(0, 0, 0, 0.1);
+  -moz-box-shadow: 0 0 3px #ffffff inset, 0 1px 1px rgba(0, 0, 0, 0.1);
+  box-shadow: 0 0 3px #ffffff inset, 0 1px 1px rgba(0, 0, 0, 0.1);
+  -webkit-background-clip: padding-box;
+  -moz-background-clip: padding-box;
+  background-clip: padding-box;
+  background-color: #f6f6f6;
+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(50%, #f6f6f6), to(#f4f4f4));
+  background-image: -webkit-linear-gradient(#ffffff, #f6f6f6 50%, #f4f4f4);
+  background-image: -moz-linear-gradient(top, #ffffff, #f6f6f6 50%, #f4f4f4);
+  background-image: -o-linear-gradient(#ffffff, #f6f6f6 50%, #f4f4f4);
+  background-image: linear-gradient(#ffffff, #f6f6f6 50%, #f4f4f4);
+  background-repeat: no-repeat;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff4f4f4', GradientType=0);
+  -moz-background-clip: padding;
+  background-color: #ffffff;
+  border: 1px solid #CCC;
+  display: block;
+  overflow: hidden;
+  white-space: nowrap;
+  position: relative;
+  height: 28px;
+  line-height: 29px;
+  padding: 0 0 0 8px;
+  color: #555555;
+  text-decoration: none;
+}
+.chzn-container-single .chzn-single span {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  margin-right: 26px;
+  display: block;
+  overflow: hidden;
+  white-space: nowrap;
+}
+.chzn-container-single .chzn-single abbr {
+  display: block;
+  position: absolute;
+  right: 26px;
+  top: 8px;
+  width: 12px;
+  height: 13px;
+  font-size: 1px;
+  background: url("chosen-sprite.png") right top no-repeat;
+}
+.chzn-container-single .chzn-single abbr:hover {
+  background-position: right -11px;
+}
+.chzn-container-single .chzn-single div {
+  position: absolute;
+  right: 0;
+  top: 0;
+  display: block;
+  height: 100%;
+  width: 18px;
+}
+.chzn-container-single .chzn-single div b {
+  background: url("chosen-sprite.png") no-repeat 0 2px;
+  display: block;
+  width: 100%;
+  height: 100%;
+}
+.chzn-container-single .chzn-search {
+  padding: 3px 4px;
+  position: relative;
+  margin: 0;
+  white-space: nowrap;
+  z-index: 1010;
+}
+.chzn-container-single .chzn-search input {
+  margin: 1px 0;
+  padding: 4px 20px 4px 5px;
+  outline: 0;
+}
+.chzn-container-single .chzn-default {
+  color: #999;
+}
+.chzn-container-single .chzn-drop {
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+  border-radius: 3px;
+  -webkit-background-clip: padding-box;
+  -moz-background-clip: padding-box;
+  background-clip: padding-box;
+  -moz-background-clip: padding;
+}
+.chzn-container-single.chzn-disabled .chzn-single abbr:hover {
+  background-position: right top;
+}
+.chzn-container-single-nosearch .chzn-search input {
+  position: absolute;
+  left: -9000px;
+}
+.chzn-container-multi .chzn-choices {
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+  border-radius: 3px;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+  -webkit-transition: border linear 0.2s;
+  -moz-transition: border linear 0.2s;
+  -o-transition: border linear 0.2s;
+  transition: border linear 0.2s;
+  -webkit-transition: box-shadow linear 0.2s;
+  -moz-transition: box-shadow linear 0.2s;
+  -o-transition: box-shadow linear 0.2s;
+  transition: box-shadow linear 0.2s;
+  background-color: #ffffff !important;
+  border: 1px solid #cccccc;
+  cursor: text;
+  overflow: hidden;
+  height: auto !important;
+  height: 1%;
+  position: relative;
+  display: block;
+  padding: 0;
+  margin: 0;
+  font-size: 14px;
+  line-height: 20px;
+  color: #555555;
+}
+.chzn-container-multi .chzn-choices li {
+  float: left;
+  list-style: none;
+}
+.chzn-container-multi .chzn-choices .search-field {
+  white-space: nowrap;
+  margin: 0;
+  padding: 0;
+}
+.chzn-container-multi .chzn-choices .search-field input {
+  -webkit-box-shadow: none;
+  -moz-box-shadow: none;
+  box-shadow: none;
+  color: #555555;
+  background: transparent !important;
+  border: 0 !important;
+  font-family: sans-serif;
+  font-size: 100%;
+  height: 15px;
+  padding: 5px;
+  margin: 1px 0 2px;
+  outline: 0;
+}
+.chzn-container-multi .chzn-choices .search-field .default {
+  color: #999;
+}
+.chzn-container-multi .chzn-choices .search-choice {
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+  border-radius: 3px;
+  -webkit-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
+  -moz-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
+  box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
+  background-color: #f6f6f6;
+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(50%, #f6f6f6), to(#f4f4f4));
+  background-image: -webkit-linear-gradient(#ffffff, #f6f6f6 50%, #f4f4f4);
+  background-image: -moz-linear-gradient(top, #ffffff, #f6f6f6 50%, #f4f4f4);
+  background-image: -o-linear-gradient(#ffffff, #f6f6f6 50%, #f4f4f4);
+  background-image: linear-gradient(#ffffff, #f6f6f6 50%, #f4f4f4);
+  background-repeat: no-repeat;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff4f4f4', GradientType=0);
+  -webkit-background-clip: padding-box;
+  -moz-background-clip: padding-box;
+  background-clip: padding-box;
+  -moz-background-clip: padding;
+  color: #555555;
+  border: 1px solid #999999;
+  line-height: 13px;
+  padding: 3px 20px 3px 5px;
+  margin: 3px 0 3px 5px;
+  position: relative;
+  cursor: default;
+}
+.chzn-container-multi .chzn-choices .search-choice .search-choice-close {
+  display: block;
+  position: absolute;
+  right: 3px;
+  top: 4px;
+  width: 12px;
+  height: 13px;
+  font-size: 1px;
+  background: url("chosen-sprite.png") right top no-repeat;
+}
+.chzn-container-multi .chzn-choices .search-choice .search-choice-close:hover {
+  background-position: right -11px;
+}
+.chzn-container-multi .chzn-choices .search-choice.search-choice-disabled {
+  background-color: #eeeeee;
+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f4f4f4), color-stop(50%, #f0f0f0), to(#e8e8e8));
+  background-image: -webkit-linear-gradient(#f4f4f4, #f0f0f0 50%, #e8e8e8);
+  background-image: -moz-linear-gradient(top, #f4f4f4, #f0f0f0 50%, #e8e8e8);
+  background-image: -o-linear-gradient(#f4f4f4, #f0f0f0 50%, #e8e8e8);
+  background-image: linear-gradient(#f4f4f4, #f0f0f0 50%, #e8e8e8);
+  background-repeat: no-repeat;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff4f4f4', endColorstr='#ffe8e8e8', GradientType=0);
+  color: #666;
+  border: 1px solid #cccccc;
+  padding-right: 5px;
+}
+.chzn-container-multi .chzn-choices .search-choice-focus {
+  background: #d4d4d4;
+}
+.chzn-container-multi .chzn-choices .search-choice-focus .search-choice-close {
+  background-position: right -11px;
+}
+.chzn-container .chzn-results {
+  margin: 0 4px 4px 0;
+  max-height: 240px;
+  padding: 0 0 0 4px;
+  position: relative;
+  overflow-x: hidden;
+  overflow-y: auto;
+  -webkit-overflow-scrolling: touch;
+}
+.chzn-container .chzn-results li {
+  display: none;
+  line-height: 15px;
+  padding: 5px 6px;
+  margin: 0;
+  list-style: none;
+}
+.chzn-container .chzn-results li em {
+  background: #feffde;
+  font-style: normal;
+}
+.chzn-container .chzn-results .no-results {
+  background: #f4f4f4;
+  display: list-item;
+}
+.chzn-container .chzn-results .group-result {
+  cursor: default;
+  color: #999;
+  font-weight: bold;
+}
+.chzn-container .chzn-results .group-option {
+  padding-left: 15px;
+}
+.chzn-container .chzn-results .active-result {
+  cursor: pointer;
+  display: list-item;
+}
+.chzn-container .chzn-results .highlighted {
+  background-color: #326dcc;
+  background-image: -moz-linear-gradient(top, #3875d7, #2a62bc);
+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#3875d7), to(#2a62bc));
+  background-image: -webkit-linear-gradient(top, #3875d7, #2a62bc);
+  background-image: -o-linear-gradient(top, #3875d7, #2a62bc);
+  background-image: linear-gradient(to bottom, #3875d7, #2a62bc);
+  background-repeat: repeat-x;
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3875d7', endColorstr='#ff2a62bc', GradientType=0);
+  color: #fff;
+}
+.chzn-container .chzn-results .highlighted em {
+  background: transparent;
+}
+.chzn-container .chzn-results-scroll {
+  background: white;
+  margin: 0 4px;
+  position: absolute;
+  text-align: center;
+  width: 321px;
+  /* This should by dynamic with js */
+
+  z-index: 1;
+}
+.chzn-container .chzn-results-scroll span {
+  display: inline-block;
+  height: 17px;
+  text-indent: -5000px;
+  width: 9px;
+}
+.chzn-container .chzn-results-scroll-down {
+  bottom: 0;
+}
+.chzn-container .chzn-results-scroll-down span {
+  background: url("chosen-sprite.png") no-repeat -4px -3px;
+}
+.chzn-container .chzn-results-scroll-up span {
+  background: url("chosen-sprite.png") no-repeat -22px -3px;
+}
+.chzn-container-multi .chzn-results {
+  margin: 4px;
+  padding: 0;
+}
+.chzn-container-multi .chzn-drop .result-selected {
+  display: none;
+}
+.chzn-container-active .chzn-single {
+  border: 1px solid #CCC;
+}
+.chzn-container-active .chzn-single .chzn-drop {
+  margin-top: -29px;
+}
+.chzn-container-active .chzn-single-with-drop {
+  -webkit-box-shadow: none;
+  -moz-box-shadow: none;
+  box-shadow: none;
+  border-color: #CCC;
+}
+.chzn-container-active .chzn-single-with-drop div {
+  background: transparent;
+  border-left: none;
+}
+.chzn-container-active .chzn-single-with-drop div b {
+  background-position: -18px 1px;
+}
+.chzn-container-active .chzn-choices {
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
+  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
+  border: 1px solid rgba(82, 168, 236, 0.8);
+  outline: 0;
+  outline: thin dotted \9;
+  /* IE6-9 */
+
+}
+.chzn-container-active .chzn-choices .search-field input {
+  color: #111 !important;
+}
+.chzn-disabled {
+  opacity: 0.005;
+  filter: alpha(opacity=0.5);
+  cursor: default;
+}
+.chzn-disabled .chzn-single {
+  cursor: default;
+}
+.chzn-disabled .search-choice-close {
+  cursor: default;
+}
+.chzn-rtl {
+  text-align: right;
+}
+.chzn-rtl .chzn-single {
+  padding: 0 8px 0 0;
+  overflow: visible;
+}
+.chzn-rtl .chzn-single span {
+  margin-left: 26px;
+  margin-right: 0;
+  direction: rtl;
+}
+.chzn-rtl .chzn-single div {
+  left: 3px;
+  right: auto;
+}
+.chzn-rtl .chzn-single abbr {
+  left: 26px;
+  right: auto;
+}
+.chzn-rtl .chzn-choices li {
+  float: right;
+}
+.chzn-rtl .chzn-choices .search-field input {
+  direction: rtl;
+}
+.chzn-rtl .chzn-choices .search-choice {
+  padding: 3px 5px 3px 19px;
+  margin: 3px 5px 3px 0;
+}
+.chzn-rtl .chzn-choices .search-choice .search-choice-close {
+  left: 4px;
+  right: auto;
+  background-position: right top;
+}
+.chzn-rtl .chzn-results .group-option {
+  padding-left: 0;
+  padding-right: 15px;
+}
+.chzn-rtl .chzn-search input {
+  padding: 4px 5px 4px 20px;
+  direction: rtl;
+}
+.chzn-rtl.chzn-container-single .chzn-results {
+  margin: 0 0 4px 4px;
+  padding: 0 4px 0 0;
+}
+.chzn-rtl.chzn-container-active .chzn-single-with-drop div {
+  border-right: none;
+}

File diff suppressed because it is too large
+ 9 - 0
apps/search/static/chosen/chosen.jquery.min.js


+ 11 - 0
apps/search/static/css/bootstrap-select.css

@@ -0,0 +1,11 @@
+a.dropdown-toggle, a.dropdown-toggle:hover {
+  text-decoration: none;
+}
+
+.dropdown a.dropdown-toggle {
+  color: gray;
+}
+
+.dropdown:hover a.dropdown-toggle, .open a.dropdown-toggle {
+  color: black;
+}

+ 13 - 0
apps/search/static/css/freshereditor.css

@@ -0,0 +1,13 @@
+.fresheditor-toolbar 
+{
+	font-family:"Georgia", Serif;
+	line-height:1.67em;
+	font-size:1em;
+}
+.toolbar-btn {
+	height: 20px;
+}
+.colorpanel {
+	background-color: #333;
+}
+

+ 51 - 0
apps/search/static/farbtastic/farbtastic.css

@@ -0,0 +1,51 @@
+/**
+ * Farbtastic Color Picker 1.2
+ * © 2008 Steven Wittens
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+.farbtastic {
+  position: relative;
+}
+.farbtastic * {
+  position: absolute;
+  cursor: crosshair;
+}
+.farbtastic, .farbtastic .wheel {
+  width: 195px;
+  height: 195px;
+}
+.farbtastic .color, .farbtastic .overlay {
+  top: 47px;
+  left: 47px;
+  width: 101px;
+  height: 101px;
+}
+.farbtastic .wheel {
+  background: url(wheel.png) no-repeat;
+  width: 195px;
+  height: 195px;
+}
+.farbtastic .overlay {
+  background: url(mask.png) no-repeat;
+}
+.farbtastic .marker {
+  width: 17px;
+  height: 17px;
+  margin: -8px 0 0 -8px;
+  overflow: hidden; 
+  background: url(marker.png) no-repeat;
+}
+

+ 345 - 0
apps/search/static/farbtastic/farbtastic.js

@@ -0,0 +1,345 @@
+/**
+ * Farbtastic Color Picker 1.2
+ * © 2008 Steven Wittens
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+jQuery.fn.farbtastic = function (callback) {
+  $.farbtastic(this, callback);
+  return this;
+};
+
+jQuery.farbtastic = function (container, callback) {
+  var container = $(container).get(0);
+  return container.farbtastic || (container.farbtastic = new jQuery._farbtastic(container, callback));
+}
+
+jQuery._farbtastic = function (container, callback) {
+  // Store farbtastic object
+  var fb = this;
+
+  // Insert markup
+  $(container).html('<div class="farbtastic"><div class="color"></div><div class="wheel"></div><div class="overlay"></div><div class="h-marker marker"></div><div class="sl-marker marker"></div></div>');
+  var e = $('.farbtastic', container);
+  fb.wheel = $('.wheel', container).get(0);
+  // Dimensions
+  fb.radius = 84;
+  fb.square = 100;
+  fb.width = 194;
+
+  // Fix background PNGs in IE6
+  if (navigator.appVersion.match(/MSIE [0-6]\./)) {
+    $('*', e).each(function () {
+      if (this.currentStyle.backgroundImage != 'none') {
+        var image = this.currentStyle.backgroundImage;
+        image = this.currentStyle.backgroundImage.substring(5, image.length - 2);
+        $(this).css({
+          'backgroundImage': 'none',
+          'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
+        });
+      }
+    });
+  }
+
+  /**
+   * Link to the given element(s) or callback.
+   */
+  fb.linkTo = function (callback) {
+    // Unbind previous nodes
+    if (typeof fb.callback == 'object') {
+      $(fb.callback).unbind('keyup', fb.updateValue);
+    }
+
+    // Reset color
+    fb.color = null;
+
+    // Bind callback or elements
+    if (typeof callback == 'function') {
+      fb.callback = callback;
+    }
+    else if (typeof callback == 'object' || typeof callback == 'string') {
+      fb.callback = $(callback);
+      fb.callback.bind('keyup', fb.updateValue);
+      if (fb.callback.get(0).value) {
+        fb.setColor(fb.callback.get(0).value);
+      }
+    }
+    return this;
+  }
+  fb.updateValue = function (event) {
+    if (this.value && this.value != fb.color) {
+      fb.setColor(this.value);
+    }
+  }
+
+  /**
+   * Change color with HTML syntax #123456
+   */
+  fb.setColor = function (color) {
+    var unpack = fb.unpack(color);
+    if (fb.color != color && unpack) {
+      fb.color = color;
+      fb.rgb = unpack;
+      fb.hsl = fb.RGBToHSL(fb.rgb);
+      fb.updateDisplay();
+    }
+    return this;
+  }
+
+  /**
+   * Change color with HSL triplet [0..1, 0..1, 0..1]
+   */
+  fb.setHSL = function (hsl) {
+    fb.hsl = hsl;
+    fb.rgb = fb.HSLToRGB(hsl);
+    fb.color = fb.pack(fb.rgb);
+    fb.updateDisplay();
+    return this;
+  }
+
+  /////////////////////////////////////////////////////
+
+  /**
+   * Retrieve the coordinates of the given event relative to the center
+   * of the widget.
+   */
+  fb.widgetCoords = function (event) {
+    var x, y;
+    var el = event.target || event.srcElement;
+    var reference = fb.wheel;
+
+    if (typeof event.offsetX != 'undefined') {
+      // Use offset coordinates and find common offsetParent
+      var pos = { x: event.offsetX, y: event.offsetY };
+
+      // Send the coordinates upwards through the offsetParent chain.
+      var e = el;
+      while (e) {
+        e.mouseX = pos.x;
+        e.mouseY = pos.y;
+        pos.x += e.offsetLeft;
+        pos.y += e.offsetTop;
+        e = e.offsetParent;
+      }
+
+      // Look for the coordinates starting from the wheel widget.
+      var e = reference;
+      var offset = { x: 0, y: 0 }
+      while (e) {
+        if (typeof e.mouseX != 'undefined') {
+          x = e.mouseX - offset.x;
+          y = e.mouseY - offset.y;
+          break;
+        }
+        offset.x += e.offsetLeft;
+        offset.y += e.offsetTop;
+        e = e.offsetParent;
+      }
+
+      // Reset stored coordinates
+      e = el;
+      while (e) {
+        e.mouseX = undefined;
+        e.mouseY = undefined;
+        e = e.offsetParent;
+      }
+    }
+    else {
+      // Use absolute coordinates
+      var pos = fb.absolutePosition(reference);
+      x = (event.pageX || 0*(event.clientX + $('html').get(0).scrollLeft)) - pos.x;
+      y = (event.pageY || 0*(event.clientY + $('html').get(0).scrollTop)) - pos.y;
+    }
+    // Subtract distance to middle
+    return { x: x - fb.width / 2, y: y - fb.width / 2 };
+  }
+
+  /**
+   * Mousedown handler
+   */
+  fb.mousedown = function (event) {
+    // Capture mouse
+    if (!document.dragging) {
+      $(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup);
+      document.dragging = true;
+    }
+
+    // Check which area is being dragged
+    var pos = fb.widgetCoords(event);
+    fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square;
+
+    // Process
+    fb.mousemove(event);
+    return false;
+  }
+
+  /**
+   * Mousemove handler
+   */
+  fb.mousemove = function (event) {
+    // Get coordinates relative to color picker center
+    var pos = fb.widgetCoords(event);
+
+    // Set new HSL parameters
+    if (fb.circleDrag) {
+      var hue = Math.atan2(pos.x, -pos.y) / 6.28;
+      if (hue < 0) hue += 1;
+      fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]);
+    }
+    else {
+      var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5));
+      var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5));
+      fb.setHSL([fb.hsl[0], sat, lum]);
+    }
+    return false;
+  }
+
+  /**
+   * Mouseup handler
+   */
+  fb.mouseup = function () {
+    // Uncapture mouse
+    $(document).unbind('mousemove', fb.mousemove);
+    $(document).unbind('mouseup', fb.mouseup);
+    document.dragging = false;
+  }
+
+  /**
+   * Update the markers and styles
+   */
+  fb.updateDisplay = function () {
+    // Markers
+    var angle = fb.hsl[0] * 6.28;
+    $('.h-marker', e).css({
+      left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px',
+      top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px'
+    });
+
+    $('.sl-marker', e).css({
+      left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px',
+      top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px'
+    });
+
+    // Saturation/Luminance gradient
+    $('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5])));
+
+    // Linked elements or callback
+    if (typeof fb.callback == 'object') {
+      // Set background/foreground color
+      $(fb.callback).css({
+        backgroundColor: fb.color,
+        color: fb.hsl[2] > 0.5 ? '#000' : '#fff'
+      });
+
+      // Change linked value
+      $(fb.callback).each(function() {
+        if (this.value && this.value != fb.color) {
+          this.value = fb.color;
+        }
+      });
+    }
+    else if (typeof fb.callback == 'function') {
+      fb.callback.call(fb, fb.color);
+    }
+  }
+
+  /**
+   * Get absolute position of element
+   */
+  fb.absolutePosition = function (el) {
+    var r = { x: el.offsetLeft, y: el.offsetTop };
+    // Resolve relative to offsetParent
+    if (el.offsetParent) {
+      var tmp = fb.absolutePosition(el.offsetParent);
+      r.x += tmp.x;
+      r.y += tmp.y;
+    }
+    return r;
+  };
+
+  /* Various color utility functions */
+  fb.pack = function (rgb) {
+    var r = Math.round(rgb[0] * 255);
+    var g = Math.round(rgb[1] * 255);
+    var b = Math.round(rgb[2] * 255);
+    return '#' + (r < 16 ? '0' : '') + r.toString(16) +
+           (g < 16 ? '0' : '') + g.toString(16) +
+           (b < 16 ? '0' : '') + b.toString(16);
+  }
+
+  fb.unpack = function (color) {
+    if (color.length == 7) {
+      return [parseInt('0x' + color.substring(1, 3)) / 255,
+        parseInt('0x' + color.substring(3, 5)) / 255,
+        parseInt('0x' + color.substring(5, 7)) / 255];
+    }
+    else if (color.length == 4) {
+      return [parseInt('0x' + color.substring(1, 2)) / 15,
+        parseInt('0x' + color.substring(2, 3)) / 15,
+        parseInt('0x' + color.substring(3, 4)) / 15];
+    }
+  }
+
+  fb.HSLToRGB = function (hsl) {
+    var m1, m2, r, g, b;
+    var h = hsl[0], s = hsl[1], l = hsl[2];
+    m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s;
+    m1 = l * 2 - m2;
+    return [this.hueToRGB(m1, m2, h+0.33333),
+        this.hueToRGB(m1, m2, h),
+        this.hueToRGB(m1, m2, h-0.33333)];
+  }
+
+  fb.hueToRGB = function (m1, m2, h) {
+    h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
+    if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+    if (h * 2 < 1) return m2;
+    if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
+    return m1;
+  }
+
+  fb.RGBToHSL = function (rgb) {
+    var min, max, delta, h, s, l;
+    var r = rgb[0], g = rgb[1], b = rgb[2];
+    min = Math.min(r, Math.min(g, b));
+    max = Math.max(r, Math.max(g, b));
+    delta = max - min;
+    l = (min + max) / 2;
+    s = 0;
+    if (l > 0 && l < 1) {
+      s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
+    }
+    h = 0;
+    if (delta > 0) {
+      if (max == r && max != g) h += (g - b) / delta;
+      if (max == g && max != b) h += (2 + (b - r) / delta);
+      if (max == b && max != r) h += (4 + (r - g) / delta);
+      h /= 6;
+    }
+    return [h, s, l];
+  }
+
+  // Install mousedown handler (the others are set on the document on-demand)
+  $('*', e).mousedown(fb.mousedown);
+
+    // Init color
+  fb.setColor('#000000');
+
+  // Set linked elements/callback
+  if (callback) {
+    fb.linkTo(callback);
+  }
+}

BIN
apps/search/static/farbtastic/marker.png


BIN
apps/search/static/farbtastic/mask.png


BIN
apps/search/static/farbtastic/wheel.png


BIN
apps/search/static/img/clear.png


BIN
apps/search/static/img/loading.gif


+ 43 - 0
apps/search/static/js/bootstrap-select.js

@@ -0,0 +1,43 @@
+/*
+ * bootstrap-select.js
+ */
+
+(function($) {
+
+  'use strict'; // jshint ;_;
+
+  $.fn.dropSelect = function(option) {
+    return this.each(function() {
+
+      var $this = $(this);
+      var display = $this.find('.dropdown-display');        // display span
+      var field = $this.find('input.dropdown-field');       // hidden input
+      var options = $this.find('ul.dropdown-menu > li > a');// select options
+
+      // when the hidden field is updated, update dropdown-toggle
+      var onFieldChange = function(event) {
+        var val = $(this).val();
+        var displayText = options.filter("[data-value='" + val + "']").html();
+        display.html(displayText);
+      };
+
+      // when an option is clicked, update the hidden field
+      var onOptionClick = function(event) {
+        // stop click from causing page refresh
+        event.preventDefault();
+        field.val($(this).attr('data-value'));
+        field.change();
+      };
+
+      field.change(onFieldChange);
+      options.click(onOptionClick);
+
+    });
+  };
+
+  // invoke on every div element with 'data-select=true'
+  $(function() {
+    $('div[data-select=true]').dropSelect();
+  });
+
+})(window.jQuery);

+ 490 - 0
apps/search/static/js/freshereditor.min.js

@@ -0,0 +1,490 @@
+(function() {
+  (function($) {
+    var methods;
+    methods = {
+      edit: function(isEditing) {
+        return this.each(function() {
+          return $(this).attr("contentEditable", isEditing || false);
+        });
+      },
+      save: function(callback) {
+        return this.each(function() {
+          return callback($(this).attr('id'), $(this).html());
+        });
+      },
+      createlink: function() {
+        var urlPrompt;
+        urlPrompt = prompt("Enter URL:", "http://");
+        return document.execCommand("createlink", false, urlPrompt);
+      },
+      insertimage: function() {
+        var urlPrompt;
+        urlPrompt = prompt("Enter Image URL:", "http://");
+        return document.execCommand("insertimage", false, urlPrompt);
+      },
+      formatblock: function(block) {
+        return document.execCommand("formatblock", null, block);
+      },
+      init: function(opts) {
+        var $toolbar, button, command, commands, excludes, font, font_list, fontnames, fontsize, fontsizes, group, groups, options, shortcuts, size_list, _i, _j, _k, _l, _len, _len2, _len3, _len4;
+        options = opts || {};
+        groups = [
+          [
+            {
+              name: 'bold',
+              label: "<span style='font-weight:bold;'>B</span>",
+              title: 'Bold (Ctrl+B)',
+              classname: 'toolbar_bold'
+            }, {
+            name: 'italic',
+            label: "<span style='font-style:italic;'>I</span>",
+            title: 'Italic (Ctrl+I)',
+            classname: 'toolbar_italic'
+          }, {
+            name: 'underline',
+            label: "<span style='text-decoration:underline!important;'>U</span>",
+            title: 'Underline (Ctrl+U)',
+            classname: 'toolbar_underline'
+          }, {
+            name: 'strikethrough',
+            label: "<span style='text-shadow:none;text-decoration:line-through;'>ABC</span>",
+            title: 'Strikethrough',
+            classname: 'toolbar_strikethrough'
+          }, {
+            name: 'removeFormat',
+            label: "<i class='icon-minus'></i>",
+            title: 'Remove Formating (Ctrl+M)',
+            classname: 'toolbar_remove'
+          }
+          ], [
+            {
+              name: 'fontname',
+              label: "F <span class='caret'></span>",
+              title: 'Select font name',
+              classname: 'toolbar_fontname dropdown-toggle',
+              dropdown: true
+            }
+          ], [
+            {
+              name: 'FontSize',
+              label: "<span style='font:bold 16px;'>A</span><span style='font-size:8px;'>A</span> <span class='caret'></span>",
+              title: 'Select font size',
+              classname: 'toolbar_fontsize dropdown-toggle',
+              dropdown: true
+            }
+          ], [
+            {
+              name: 'forecolor',
+              label: "<div style='color:#ff0000;'>A <span class='caret'></span></div>",
+              title: 'Select font color',
+              classname: 'toolbar_forecolor dropdown-toggle',
+              dropdown: true
+            }
+          ], [
+            {
+              name: 'backcolor',
+              label: "<div style='display:inline-block;margin:3px;width:15px;height:12px;background-color:#0000ff;'></div> <span class='caret'></span>",
+              title: 'Select background color',
+              classname: 'toolbar_bgcolor dropdown-toggle',
+              dropdown: true
+            }
+          ], [
+            {
+              name: 'justifyleft',
+              label: "<i class='icon-align-left' style='margin-top:2px;'></i>",
+              title: 'Left justify',
+              classname: 'toolbar_justifyleft'
+            }, {
+              name: 'justifycenter',
+              label: "<i class='icon-align-center' style='margin-top:2px;'></i>",
+              title: 'Center justify',
+              classname: 'toolbar_justifycenter'
+            }, {
+              name: 'justifyright',
+              label: "<i class='icon-align-right' style='margin-top:2px;'></i>",
+              title: 'Right justify',
+              classname: 'toolbar_justifyright'
+            }, {
+              name: 'justifyfull',
+              label: "<i class='icon-align-justify' style='margin-top:2px;'></i>",
+              title: 'Full justify',
+              classname: 'toolbar_justifyfull'
+            }
+          ], [
+            {
+              name: 'createlink',
+              label: '@',
+              title: 'Link to a web page (Ctrl+L)',
+              userinput: "yes",
+              classname: 'toolbar_link'
+            }, {
+              name: 'insertimage',
+              label: "<i style='margin-top:2px;' class='icon-picture'></i>",
+              title: 'Insert an image (Ctrl+G)',
+              userinput: "yes",
+              classname: 'toolbar_image'
+            }, {
+              name: 'insertorderedlist',
+              label: "<i class='icon-list-alt' style='margin-top:2px;'></i>",
+              title: 'Insert ordered list',
+              classname: 'toolbar_ol'
+            }, {
+              name: 'insertunorderedlist',
+              label: "<i class='icon-list' style='margin-top:2px;'></i>",
+              title: 'Insert unordered list',
+              classname: 'toolbar_ul'
+            }
+          ], [
+            {
+              name: 'insertparagraph',
+              label: 'P',
+              title: 'Insert a paragraph (Ctrl+Alt+0)',
+              classname: 'toolbar_p',
+              block: 'p'
+            }, {
+              name: 'insertheading1',
+              label: 'H1',
+              title: "Heading 1 (Ctrl+Alt+1)",
+              classname: 'toolbar_h1',
+              block: 'h1'
+            }, {
+              name: 'insertheading2',
+              label: 'H2',
+              title: "Heading 2 (Ctrl+Alt+2)",
+              classname: 'toolbar_h2',
+              block: 'h2'
+            }, {
+              name: 'insertheading3',
+              label: 'H3',
+              title: "Heading 3 (Ctrl+Alt+3)",
+              classname: 'toolbar_h3',
+              block: 'h3'
+            }, {
+              name: 'insertheading4',
+              label: 'H4',
+              title: "Heading 4 (Ctrl+Alt+4)",
+              classname: 'toolbar_h4',
+              block: 'h4'
+            }
+          ], [
+            {
+              name: 'blockquote',
+              label: "<i style='margin-top:2px;' class='icon-comment'></i>",
+              title: 'Blockquote (Ctrl+Q)',
+              classname: 'toolbar_blockquote',
+              block: 'blockquote'
+            }, {
+              name: 'code',
+              label: '{&nbsp;}',
+              title: 'Code (Ctrl+Alt+K)',
+              classname: 'toolbar_code',
+              block: 'pre'
+            }, {
+              name: 'superscript',
+              label: 'x<sup>2</sup>',
+              title: 'Superscript',
+              classname: 'toolbar_superscript'
+            }, {
+              name: 'subscript',
+              label: 'x<sub>2</sub>',
+              title: 'Subscript',
+              classname: 'toolbar_subscript'
+            }
+          ]
+        ];
+        if (options.toolbar_selector != null) {
+          $toolbar = $(options.toolbar_selector);
+        } else {
+          $(this).before("<div id='editor-toolbar'></div>");
+          $toolbar = $('#editor-toolbar');
+        }
+        $toolbar.addClass('fresheditor-toolbar');
+        $toolbar.append("<div class='btn-toolbar'></div>");
+        excludes = options.excludes || [];
+        for (_i = 0, _len = groups.length; _i < _len; _i++) {
+          commands = groups[_i];
+          group = '';
+          for (_j = 0, _len2 = commands.length; _j < _len2; _j++) {
+            command = commands[_j];
+            if (jQuery.inArray(command.name, excludes) < 0) {
+              button = "<a href='#' class='btn toolbar-btn toolbar-cmd " + command.classname + "' title='" + command.title + "' command='" + command.name + "'";
+              if (command.userinput != null) {
+                button += " userinput='" + command.userinput + "'";
+              }
+              if (command.block != null) {
+                button += " block='" + command.block + "'";
+              }
+              if (command.dropdown) {
+                button += " data-toggle='dropdown'";
+              }
+              button += ">" + command.label + "</a>";
+              group += button;
+            }
+          }
+          $('.btn-toolbar', $toolbar).append("<div class='btn-group'>" + group + "</div>");
+        }
+        $("[data-toggle='dropdown']").removeClass('toolbar-cmd');
+        if (jQuery.inArray('fontname', excludes) < 0) {
+          fontnames = ["Arial", "Arial Black", "Comic Sans MS", "Courier New", "Georgia", "Helvetica", "Sans Serif", "Tahoma", "Times New Roman", "Trebuchet MS", "Verdana"];
+          font_list = '';
+          for (_k = 0, _len3 = fontnames.length; _k < _len3; _k++) {
+            font = fontnames[_k];
+            font_list += "<li><a href='#' class='fontname-option' style='font-family:" + font + ";'>" + font + "</a></li>";
+          }
+          $('.toolbar_fontname').after("<ul class='dropdown-menu'>" + font_list + "</ul>");
+          $('.fontname-option').on('click', function() {
+            document.execCommand("fontname", false, $(this).text());
+            $(this).closest('.btn-group').removeClass('open');
+            return false;
+          });
+        }
+        if (jQuery.inArray('FontSize', excludes) < 0) {
+          fontsizes = [
+            {
+              size: 1,
+              point: 8
+            }, {
+              size: 2,
+              point: 10
+            }, {
+              size: 3,
+              point: 12
+            }, {
+              size: 4,
+              point: 14
+            }, {
+              size: 5,
+              point: 18
+            }, {
+              size: 6,
+              point: 24
+            }, {
+              size: 7,
+              point: 36
+            }
+          ];
+          size_list = '';
+          for (_l = 0, _len4 = fontsizes.length; _l < _len4; _l++) {
+            fontsize = fontsizes[_l];
+            size_list += "<li><a href='#' class='font-option fontsize-option' style='font-size:" + fontsize.point + "px;' fontsize='" + fontsize.size + "'>" + fontsize.size + "(" + fontsize.point + "pt)</a></li>";
+          }
+          $('.toolbar_fontsize').after("<ul class='dropdown-menu'>" + size_list + "</ul>");
+          $('a.fontsize-option').on('click', function() {
+            console.log($(this).attr('fontsize'));
+            document.execCommand("FontSize", false, $(this).attr('fontsize'));
+            $(this).closest('.btn-group').removeClass('open');
+            return false;
+          });
+        }
+        if (jQuery.inArray('forecolor', excludes) < 0) {
+          $('a.toolbar_forecolor').after("<ul class='dropdown-menu colorpanel'><input type='text' id='forecolor-input' value='#000000' /><div id='forecolor-picker'></div></ul>");
+          $('#forecolor-picker').farbtastic(function(color) {
+            $('#forecolor-input').val(color);
+            document.execCommand("forecolor", false, color);
+            $(this).closest('.btn-group').removeClass('open');
+            $('.toolbar_forecolor div').css({
+              "color": color
+            });
+            return false;
+          });
+        }
+        if (jQuery.inArray('backcolor', excludes) < 0) {
+          $('a.toolbar_bgcolor').after("<ul class='dropdown-menu colorpanel'><input type='text' id='bgcolor-input' value='#000000' /><div id='bgcolor-picker'></div></ul>");
+          $('#bgcolor-picker').farbtastic(function(color) {
+            $('#bgcolor-input').val(color);
+            document.execCommand("backcolor", false, color);
+            $(this).closest('.btn-group').removeClass('open');
+            $('.toolbar_bgcolor div').css({
+              "background-color": color
+            });
+            return false;
+          });
+        }
+        $(this).on('focus', function() {
+          var $this;
+          $this = $(this);
+          $this.data('before', $this.html());
+          return $this;
+        }).on('blur keyup paste', function() {
+              var $this;
+              $this = $(this);
+              if ($this.data('before') !== $this.html()) {
+                $this.data('before', $this.html());
+                $this.trigger('change');
+              }
+              return $this;
+            });
+        $("a.toolbar-cmd").on('click', function() {
+          var ceNode, cmd, dummy, range;
+          cmd = $(this).attr('command');
+          if ($(this).attr('userinput') === 'yes') {
+            methods[cmd].apply(this);
+          } else if ($(this).attr('block')) {
+            methods['formatblock'].apply(this, ["<" + ($(this).attr('block')) + ">"]);
+          } else {
+            if ((cmd === 'justifyright') || (cmd === 'justifyleft') || (cmd === 'justifycenter') || (cmd === 'justifyfull')) {
+              try {
+                document.execCommand(cmd, false, null);
+              } catch (e) {
+                if (e && e.result === 2147500037) {
+                  range = window.getSelection().getRangeAt(0);
+                  dummy = document.createElement('br');
+                  ceNode = range.startContainer.parentNode;
+                  while ((ceNode != null) && ceNode.contentEditable !== 'true') {
+                    ceNode = ceNode.parentNode;
+                  }
+                  if (!ceNode) {
+                    throw 'Selected node is not editable!';
+                  }
+                  ceNode.insertBefore(dummy, ceNode.childNodes[0]);
+                  document.execCommand(cmd, false, null);
+                  dummy.parentNode.removeChild(dummy);
+                } else if (console && console.log) {
+                  console.log(e);
+                }
+              }
+            } else {
+              document.execCommand(cmd, false, null);
+            }
+          }
+          return false;
+        });
+        shortcuts = [
+          {
+            keys: 'Ctrl+l',
+            method: function() {
+              return methods.createlink.apply(this);
+            }
+          }, {
+            keys: 'Ctrl+g',
+            method: function() {
+              return methods.insertimage.apply(this);
+            }
+          }, {
+            keys: 'Ctrl+Alt+U',
+            method: function() {
+              return document.execCommand('insertunorderedlist', false, null);
+            }
+          }, {
+            keys: 'Ctrl+Alt+O',
+            method: function() {
+              return document.execCommand('insertorderedlist', false, null);
+            }
+          }, {
+            keys: 'Ctrl+q',
+            method: function() {
+              return methods.formatblock.apply(this, ["<blockquote>"]);
+            }
+          }, {
+            keys: 'Ctrl+Alt+k',
+            method: function() {
+              return methods.formatblock.apply(this, ["<pre>"]);
+            }
+          }, {
+            keys: 'Ctrl+.',
+            method: function() {
+              return document.execCommand('superscript', false, null);
+            }
+          }, {
+            keys: 'Ctrl+Shift+.',
+            method: function() {
+              return document.execCommand('subscript', false, null);
+            }
+          }, {
+            keys: 'Ctrl+Alt+0',
+            method: function() {
+              return methods.formatblock.apply(this, ["p"]);
+            }
+          }, {
+            keys: 'Ctrl+b',
+            method: function() {
+              return document.execCommand('bold', false, null);
+            }
+          }, {
+            keys: 'Ctrl+i',
+            method: function() {
+              return document.execCommand('italic', false, null);
+            }
+          }, {
+            keys: 'Ctrl+Alt+1',
+            method: function() {
+              return methods.formatblock.apply(this, ["H1"]);
+            }
+          }, {
+            keys: 'Ctrl+Alt+2',
+            method: function() {
+              return methods.formatblock.apply(this, ["H2"]);
+            }
+          }, {
+            keys: 'Ctrl+Alt+3',
+            method: function() {
+              return methods.formatblock.apply(this, ["H3"]);
+            }
+          }, {
+            keys: 'Ctrl+Alt+4',
+            method: function() {
+              return methods.formatblock.apply(this, ["H4"]);
+            }
+          }, {
+            keys: 'Ctrl+m',
+            method: function() {
+              return document.execCommand("removeFormat", false, null);
+            }
+          }, {
+            keys: 'Ctrl+u',
+            method: function() {
+              return document.execCommand('underline', false, null);
+            }
+          }, {
+            keys: 'tab',
+            method: function() {
+              return document.execCommand('indent', false, null);
+            }
+          }, {
+            keys: 'Ctrl+tab',
+            method: function() {
+              return document.execCommand('indent', false, null);
+            }
+          }, {
+            keys: 'Shift+tab',
+            method: function() {
+              return document.execCommand('outdent', false, null);
+            }
+          }
+        ];
+        $.each(shortcuts, function(index, elem) {
+          return shortcut.add(elem.keys, function() {
+            elem.method();
+            return false;
+          }, {
+            'type': 'keydown',
+            'propagate': false
+          });
+        });
+        return this.each(function() {
+          var $this, data, tooltip;
+          $this = $(this);
+          data = $this.data('fresheditor');
+          tooltip = $('<div/>', {
+            text: $this.attr('title')
+          });
+          if (!data) {
+            return $(this).data('fresheditor', {
+              target: $this,
+              tooltip: tooltip
+            });
+          }
+        });
+      }
+    };
+    return $.fn.freshereditor = function(method) {
+      if (methods[method]) {
+        methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
+      } else if (typeof method === 'object' || !method) {
+        methods.init.apply(this, arguments);
+      } else {
+        $.error('Method ' + method + ' does not exist on jQuery.contentEditable');
+      }
+    };
+  })(jQuery);
+}).call(this);

File diff suppressed because it is too large
+ 1 - 0
apps/search/static/js/knockout-sortable.min.js


+ 226 - 0
apps/search/static/js/shortcut.js

@@ -0,0 +1,226 @@
+/**
+* http://www.openjs.com/scripts/events/keyboard_shortcuts/
+* Version : 2.01.B
+* By Binny V A
+* License : BSD
+*/
+var shortcut = {
+	'all_shortcuts': {}, //All the shortcuts are stored in this array
+	'add': function (shortcut_combination, callback, opt) {
+		//Provide a set of default options
+		var default_options = {
+			'type': 'keydown',
+			'propagate': false,
+			'disable_in_input': false,
+			'target': document,
+			'keycode': false
+		};
+		if (!opt) {
+			opt = default_options;
+		}
+		else {
+			var dfo;
+			for (dfo in default_options) {
+				if (typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];
+			}
+		}
+
+		var ele = opt.target;
+		if (typeof opt.target == 'string') ele = document.getElementById(opt.target);
+		var ths = this;
+		shortcut_combination = shortcut_combination.toLowerCase();
+
+		//The function to be called at keypress
+		var func = function (e) {
+			e = e || window.event;
+
+			if (opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields
+				var element;
+				if (e.target) element = e.target;
+				else if (e.srcElement) element = e.srcElement;
+				if (element.nodeType == 3) element = element.parentNode;
+
+				if (element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return;
+			}
+
+			//Find Which key is pressed
+			if (e.keyCode) code = e.keyCode;
+			else if (e.which) code = e.which;
+			var character = String.fromCharCode(code).toLowerCase();
+
+			if (code == 188) character = ","; //If the user presses , when the type is onkeydown
+			if (code == 190) character = "."; //If the user presses , when the type is onkeydown
+
+			var keys = shortcut_combination.split("+");
+			//Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
+			var kp = 0;
+
+			//Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
+			var shift_nums = {
+				"`": "~",
+				"1": "!",
+				"2": "@",
+				"3": "#",
+				"4": "$",
+				"5": "%",
+				"6": "^",
+				"7": "&",
+				"8": "*",
+				"9": "(",
+				"0": ")",
+				"-": "_",
+				"=": "+",
+				";": ":",
+				"'": "\"",
+				",": "<",
+				".": ">",
+				"/": "?",
+				"\\": "|"
+			}
+			//Special Keys - and their codes
+			var special_keys = {
+				'esc': 27,
+				'escape': 27,
+				'tab': 9,
+				'space': 32,
+				'return': 13,
+				'enter': 13,
+				'backspace': 8,
+
+				'scrolllock': 145,
+				'scroll_lock': 145,
+				'scroll': 145,
+				'capslock': 20,
+				'caps_lock': 20,
+				'caps': 20,
+				'numlock': 144,
+				'num_lock': 144,
+				'num': 144,
+
+				'pause': 19,
+				'break': 19,
+
+				'insert': 45,
+				'home': 36,
+				'delete': 46,
+				'end': 35,
+
+				'pageup': 33,
+				'page_up': 33,
+				'pu': 33,
+
+				'pagedown': 34,
+				'page_down': 34,
+				'pd': 34,
+
+				'left': 37,
+				'up': 38,
+				'right': 39,
+				'down': 40,
+
+				'f1': 112,
+				'f2': 113,
+				'f3': 114,
+				'f4': 115,
+				'f5': 116,
+				'f6': 117,
+				'f7': 118,
+				'f8': 119,
+				'f9': 120,
+				'f10': 121,
+				'f11': 122,
+				'f12': 123
+			}
+
+			var modifiers = {
+				shift: { wanted: false, pressed: false },
+				ctrl: { wanted: false, pressed: false },
+				alt: { wanted: false, pressed: false },
+				meta: { wanted: false, pressed: false}	//Meta is Mac specific
+			};
+
+			if (e.ctrlKey) modifiers.ctrl.pressed = true;
+			if (e.shiftKey) modifiers.shift.pressed = true;
+			if (e.altKey) modifiers.alt.pressed = true;
+			if (e.metaKey) modifiers.meta.pressed = true;
+
+			for (var i = 0; k = keys[i], i < keys.length; i++) {
+				//Modifiers
+				if (k == 'ctrl' || k == 'control') {
+					kp++;
+					modifiers.ctrl.wanted = true;
+
+				} else if (k == 'shift') {
+					kp++;
+					modifiers.shift.wanted = true;
+
+				} else if (k == 'alt') {
+					kp++;
+					modifiers.alt.wanted = true;
+				} else if (k == 'meta') {
+					kp++;
+					modifiers.meta.wanted = true;
+				} else if (k.length > 1) { //If it is a special key
+					if (special_keys[k] == code) kp++;
+
+				} else if (opt['keycode']) {
+					if (opt['keycode'] == code) kp++;
+
+				} else { //The special keys did not match
+					if (character == k) kp++;
+					else {
+						if (shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
+							character = shift_nums[character];
+							if (character == k) kp++;
+						}
+					}
+				}
+			}
+
+			if (kp == keys.length &&
+						modifiers.ctrl.pressed == modifiers.ctrl.wanted &&
+						modifiers.shift.pressed == modifiers.shift.wanted &&
+						modifiers.alt.pressed == modifiers.alt.wanted &&
+						modifiers.meta.pressed == modifiers.meta.wanted) {
+				callback(e);
+
+				if (!opt['propagate']) { //Stop the event
+					//e.cancelBubble is supported by IE - this will kill the bubbling process.
+					e.cancelBubble = true;
+					e.returnValue = false;
+
+					//e.stopPropagation works in Firefox.
+					if (e.stopPropagation) {
+						e.stopPropagation();
+						e.preventDefault();
+					}
+					return false;
+				}
+			}
+		}
+		this.all_shortcuts[shortcut_combination] = {
+			'callback': func,
+			'target': ele,
+			'event': opt['type']
+		};
+		//Attach the function with the event
+		if (ele.addEventListener) ele.addEventListener(opt['type'], func, false);
+		else if (ele.attachEvent) ele.attachEvent('on' + opt['type'], func);
+		else ele['on' + opt['type']] = func;
+	},
+
+	//Remove the shortcut - just specify the shortcut and I will remove the binding
+	'remove': function (shortcut_combination) {
+		shortcut_combination = shortcut_combination.toLowerCase();
+		var binding = this.all_shortcuts[shortcut_combination];
+		delete (this.all_shortcuts[shortcut_combination])
+		if (!binding) return;
+		var type = binding['event'];
+		var ele = binding['target'];
+		var callback = binding['callback'];
+
+		if (ele.detachEvent) ele.detachEvent('on' + type, callback);
+		else if (ele.removeEventListener) ele.removeEventListener(type, callback, false);
+		else ele['on' + type] = false;
+	}
+}

Some files were not shown because too many files changed in this diff