579 lines
		
	
	
		
			No EOL
		
	
	
		
			19 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			579 lines
		
	
	
		
			No EOL
		
	
	
		
			19 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html5>
 | |
| <html>
 | |
| <head>
 | |
|     {% import "photo_card.html" as photo_card %}
 | |
|     {% import "header.html" as header %}
 | |
|     <title>Search</title>
 | |
|     <meta charset="UTF-8">
 | |
|     <link rel="stylesheet" href="/static/common.css">
 | |
|     <script src="/static/common.js"></script>
 | |
| 
 | |
| <style>
 | |
| form
 | |
| {
 | |
|     display: flex;
 | |
|     flex-direction: column;
 | |
|     justify-content: center;
 | |
| 
 | |
|     width: 100%;
 | |
| }
 | |
| #error_message_area
 | |
| {
 | |
|     display: flex;
 | |
|     flex-direction: column;
 | |
|     justify-content: center;
 | |
|     align-items: center;
 | |
| }
 | |
| .search_warning
 | |
| {
 | |
|     align-self: center;
 | |
| 
 | |
|     padding: 2px;
 | |
| 
 | |
|     background-color: #f00;
 | |
| 
 | |
|     color: #fff;
 | |
| }
 | |
| #left, #right
 | |
| {
 | |
|     /* Keep the prev-next buttons from scraping the floor */
 | |
|     /*padding-bottom: 30px;*/
 | |
| }
 | |
| #left
 | |
| {
 | |
|     flex: 1;
 | |
| 
 | |
|     padding: 8px;
 | |
|     max-width: 300px;
 | |
|     min-width: 300px;
 | |
|     width: 300px;
 | |
| 
 | |
|     background-color: rgba(0, 0, 0, 0.1);
 | |
| 
 | |
|     word-wrap: break-word;
 | |
| }
 | |
| #right
 | |
| {
 | |
|     flex: 1;
 | |
| 
 | |
|     padding: 8px;
 | |
| 
 | |
|     width: auto;
 | |
| }
 | |
| @media screen and (max-width: 800px) {
 | |
|     #content_body
 | |
|     {
 | |
|         flex-direction: column-reverse;
 | |
|     }
 | |
|     #left
 | |
|     {
 | |
|         max-width: none;
 | |
|         width: initial;
 | |
|     }
 | |
| }
 | |
| .prev_next_holder
 | |
| {
 | |
|     display: flex;
 | |
|     flex-direction: row;
 | |
| }
 | |
| .prev_page
 | |
| {
 | |
|     margin-right: 10px;
 | |
| }
 | |
| .next_page
 | |
| {
 | |
|     margin-left: 10px;
 | |
| }
 | |
| .prev_page, .next_page
 | |
| {
 | |
|     display: flex;
 | |
|     flex: 1;
 | |
|     justify-content: center;
 | |
| 
 | |
|     border: 1px solid black;
 | |
| 
 | |
|     background-color: #ffffd4;
 | |
| 
 | |
|     font-size: 20;
 | |
| }
 | |
| 
 | |
| .search_builder_tagger,
 | |
| #search_builder_orderby_ul
 | |
| {
 | |
|     margin: 0;
 | |
| }
 | |
| </style>
 | |
| 
 | |
| {% macro prev_next_buttons() %}
 | |
| {% if prev_page_url or next_page_url %}
 | |
| <div class="prev_next_holder">
 | |
|     {% if prev_page_url %}
 | |
|     <a class="prev_page" href="{{prev_page_url}}">Previous</a>
 | |
|     {% else %}
 | |
|     <a class="prev_page"><br></a>
 | |
|     {% endif %}
 | |
|     {% if next_page_url %}
 | |
|     <a class="next_page" href="{{next_page_url}}">Next</a>
 | |
|     {% else %}
 | |
|     <a class="next_page"><br></a>
 | |
|     {% endif %}
 | |
| </div>
 | |
| {% endif %}
 | |
| {% endmacro %}
 | |
| 
 | |
| {% macro create_orderby_li(selected_column, selected_sorter) %}
 | |
| <li class="search_builder_orderby_li">
 | |
|     <select>
 | |
|         <option value="created"   {%if selected_column=="created"%}selected{%endif%}  >Creation date</option>
 | |
|         <option value="area"      {%if selected_column=="area"%}selected{%endif%}     >Area</option>
 | |
|         <option value="width"     {%if selected_column=="width"%}selected{%endif%}    >Width</option>
 | |
|         <option value="height"    {%if selected_column=="height"%}selected{%endif%}   >Height</option>
 | |
|         <option value="ratio"     {%if selected_column=="ratio"%}selected{%endif%}    >Aspect Ratio</option>
 | |
|         <option value="bytes"     {%if selected_column=="bytes"%}selected{%endif%}    >File size</option>
 | |
|         <option value="duration"  {%if selected_column=="duration"%}selected{%endif%} >Duration</option>
 | |
|         <option value="tagged_at" {%if selected_column=="tagged_at"%}selected{%endif%}>Recently tagged</option>
 | |
|         <option value="random"    {%if selected_column=="random"%}selected{%endif%}   >Random</option>
 | |
|     </select>
 | |
|     <select>
 | |
|         <option value="desc" {%if selected_sorter=="desc"%}selected{%endif%} >Descending</option>
 | |
|         <option value="asc"  {%if selected_sorter=="asc"%}selected{%endif%} >Ascending</option>
 | |
|     </select>
 | |
|     <button class="remove_tag_button_perm" onclick="orderby_remove_hook(this);"></button>
 | |
| </li>
 | |
| {% endmacro %}
 | |
| </head>
 | |
| 
 | |
| 
 | |
| <body>
 | |
|     {{header.make_header(session=session)}}
 | |
|     <div id="error_message_area">
 | |
|         {% for warning in warnings %}
 | |
|         <span class="search_warning">{{warning}}</span>
 | |
|         {% endfor %}
 | |
|     </div>
 | |
|     <div id="content_body">
 | |
|     <div id="left">
 | |
|         {% for tagtype in ["musts", "mays", "forbids"] %}
 | |
|         <div id="search_builder_{{tagtype}}" {% if search_kwargs["tag_expression"]%}style="display:none"{%endif%}>
 | |
|             <span>Tag {{tagtype}}:</span>
 | |
|             <ul class="search_builder_tagger">
 | |
|                 {% set key="tag_" + tagtype %}
 | |
|                 {% if search_kwargs[key] %}
 | |
|                 {% for tagname in search_kwargs[key] %}
 | |
|                 <li class="search_builder_{{tagtype}}_inputted">
 | |
|                     <span class="tag_object">{{tagname}}</span><!--
 | |
|                     --><button class="remove_tag_button"
 | |
|                     onclick="remove_searchtag(this, '{{tagname}}', inputted_{{tagtype}});"></button>
 | |
|                 </li>
 | |
|                 {% endfor %}
 | |
|                 {% endif %}
 | |
|                 <li><input id="search_builder_{{tagtype}}_input" type="text"></li>
 | |
|             </ul>
 | |
|         </div>
 | |
|         {% endfor %}
 | |
|         <div id="search_builder_expression" {% if not search_kwargs["tag_expression"]%}style="display:none"{%endif%}>
 | |
|             <span>Tag Expression:</span>
 | |
|             <input id="search_builder_expression_input" name="tag_expression" type="text"
 | |
|             {% if search_kwargs["tag_expression"] %}
 | |
|             value="{{search_kwargs["tag_expression"]}}"
 | |
|             {% endif %}
 | |
|             >
 | |
|         </div>
 | |
|         <div id="search_builder_orderby">
 | |
|             <span>Order by</span>
 | |
|             <ul id="search_builder_orderby_ul">
 | |
|                 {% if "orderby" in search_kwargs and search_kwargs["orderby"] %}
 | |
|                 {% for orderby in search_kwargs["orderby"] %}
 | |
|                     {% set column, sorter=orderby.split("-") %}
 | |
|                     {{ create_orderby_li(selected_column=column, selected_sorter=sorter) }}
 | |
|                 {% endfor %}
 | |
|                 {% else %}
 | |
|                 {{ create_orderby_li(selected_column=0, selected_sorter=0) }}
 | |
|                 {% endif %}
 | |
|                 <li id="search_builder_orderby_newrow"><button class="add_tag_button" onclick="add_new_orderby()">+</button></li>
 | |
|             </ul>
 | |
|         </div>
 | |
|         <br>
 | |
|         <form id="search_builder_form" action="" onsubmit="return submit_search();">
 | |
| 
 | |
|             <span>Min-max values</span>
 | |
|             <input type="text" class="basic_param"
 | |
|             value="{%if search_kwargs['area']%}{{search_kwargs['area']}}{%endif%}"
 | |
|             name="area" placeholder="Area: 1m-2m">
 | |
| 
 | |
|             <input type="text" class="basic_param"
 | |
|             value="{%if search_kwargs['width']%}{{search_kwargs['width']}}{%endif%}"
 | |
|             name="width" placeholder="Width: 1k-2k">
 | |
| 
 | |
|             <input type="text" class="basic_param"
 | |
|             value="{%if search_kwargs['height']%}{{search_kwargs['height']}}{%endif%}"
 | |
|             name="height" placeholder="Height: 1k-2k">
 | |
| 
 | |
|             <input type="text" class="basic_param"
 | |
|             value="{%if search_kwargs['ratio']%}{{search_kwargs['ratio']}}{%endif%}"
 | |
|             name="ratio" placeholder="Aspect Ratio: 1.7-2">
 | |
| 
 | |
|             <input type="text" class="basic_param"
 | |
|             value="{%if search_kwargs['bytes']%}{{search_kwargs['bytes']}}{%endif%}"
 | |
|             name="bytes" placeholder="File Size: 1mb-2mb">
 | |
| 
 | |
|             <input type="text" class="basic_param"
 | |
|             value="{%if search_kwargs['duration']%}{{search_kwargs['duration']}}{%endif%}"
 | |
|             name="duration" placeholder="Duration: 10:00-20:00">
 | |
| 
 | |
|             <br>
 | |
| 
 | |
|             <span>Other filters</span>
 | |
|             <input type="text" class="basic_param"
 | |
|             value="{%if search_kwargs['filename']%}{{search_kwargs['filename']}}{%endif%}"
 | |
|             name="filename" placeholder="Filename">
 | |
| 
 | |
|             <input type="text" class="basic_param"
 | |
|             value="{%if search_kwargs['mimetype']%}{{search_kwargs['mimetype']}}{%endif%}"
 | |
|             name="mimetype" placeholder="Mimetype(s)">
 | |
| 
 | |
|             <input type="text" class="basic_param"
 | |
|             value="{%if search_kwargs['extension']%}{{search_kwargs['extension']}}{%endif%}"
 | |
|             name="extension" placeholder="Extension(s)">
 | |
| 
 | |
|             <input type="text" class="basic_param"
 | |
|             value="{%if search_kwargs['extension_not']%}{{search_kwargs['extension_not']}}{%endif%}" 
 | |
|             name="extension_not" placeholder="Forbid extension(s)">
 | |
|             
 | |
|             <select name="limit" class="basic_param">
 | |
|                 {% set limit_options = [20, 50, 100] %}
 | |
|                 {% if search_kwargs['limit'] not in limit_options %}
 | |
|                     {% do limit_options.append(search_kwargs['limit']) %}
 | |
|                     {% do limit_options.sort() %}
 | |
|                 {% endif %}
 | |
|                 {% for limit_option in limit_options %}
 | |
|                 <option
 | |
|                 value="{{limit_option}}"
 | |
|                 {{"selected" if search_kwargs['limit'] == limit_option else ""}}
 | |
|                 >
 | |
|                 {{limit_option}} items
 | |
|                 </option>
 | |
|                 {% endfor %}
 | |
|             </select>
 | |
|             <select name="has_tags" class="basic_param">
 | |
|                 <option value=""   {%if search_kwargs['has_tags'] == None %}selected{%endif%}>Tagged and untagged</option>
 | |
|                 <option value="yes"{%if search_kwargs['has_tags'] == True %}selected{%endif%}>Tagged only</option>
 | |
|                 <option value="no" {%if search_kwargs['has_tags'] == False %}selected{%endif%}>Untagged only</option>
 | |
|             </select>
 | |
|             <select name="view" class="basic_param">
 | |
|                 <option value="grid" {%if search_kwargs['view'] == "grid" %}selected{%endif%}>Grid</option>
 | |
|                 <option value="list" {%if search_kwargs['view'] == "list" %}selected{%endif%}>List</option>
 | |
|             </select>
 | |
|             <button type="submit" id="search_go_button" value="">Search</button>
 | |
|         </form>
 | |
|         {% if total_tags %}
 | |
|         <span>Tags on this page (click to join query):</span>
 | |
|         <ul>
 | |
|             {% for tag in total_tags %}
 | |
|             <li><a href="" class="tag_object">{{tag}}</a></li>
 | |
|             {% endfor %}
 | |
|         </ul>
 | |
|         {% endif %}
 | |
|     </div>
 | |
|     <div id="right">
 | |
|         <p>You got {{photos|length}} items</p>
 | |
|         {{prev_next_buttons()}}
 | |
|         <div id="search_results_holder">
 | |
|         {% for photo in photos %}
 | |
|         {{photo_card.create_photo_card(photo, view=search_kwargs["view"])}}
 | |
|         {% endfor %}
 | |
|         </div>
 | |
| 
 | |
|         {{prev_next_buttons()}}
 | |
|     </div>
 | |
|     </div>
 | |
| </body>
 | |
| 
 | |
| 
 | |
| <script type="text/javascript">
 | |
| PARAM_DEFAULTS = {
 | |
|     'limit': 50,
 | |
|     'view': 'grid',
 | |
| }
 | |
| function add_searchtag(box, value, inputted_list, li_class)
 | |
| {
 | |
|     /*
 | |
|     Called by hitting Enter within a must/may/forbid field. Checks whether the tag exists
 | |
|     and adds it to the query.
 | |
|     */
 | |
|     if (box.offsetParent === null)
 | |
|     {
 | |
|         // The box is hidden probably because we're in Expression mode.
 | |
|         return;
 | |
|     }
 | |
|     console.log("adding " + value);
 | |
|     var already_have = false;
 | |
|     // We're going to be doing some in-place splicing to remove,
 | |
|     // so make a duplicate for iterating
 | |
|     existing_tags = Array.from(inputted_list);
 | |
|     for (var index = 0; index < existing_tags.length; index += 1)
 | |
|     {
 | |
|         existing_tag = existing_tags[index];
 | |
|         if (existing_tag == value)
 | |
|         {
 | |
|             already_have = true;
 | |
|         }
 | |
|         else if (existing_tag.startsWith(value + ".") || value.startsWith(existing_tag + "."))
 | |
|         {
 | |
|             remove_searchtag(box, existing_tag, inputted_list);
 | |
|         }
 | |
|     }
 | |
|     if (!already_have)
 | |
|     {
 | |
|         inputted_list.push(value);
 | |
|         var new_li = document.createElement("li");
 | |
|         new_li.className = li_class;
 | |
| 
 | |
|         var new_span = document.createElement("span");
 | |
|         new_span.className = "tag_object";
 | |
|         new_span.innerHTML = value;
 | |
| 
 | |
|         var new_delbutton = document.createElement("button")
 | |
|         new_delbutton.className = "remove_tag_button";
 | |
|         new_delbutton.onclick = function(){remove_searchtag(new_delbutton, value, inputted_list)};
 | |
| 
 | |
|         new_li.appendChild(new_span);
 | |
|         new_li.appendChild(new_delbutton);
 | |
| 
 | |
|         box_li = box.parentElement;
 | |
|         ul = box_li.parentElement;
 | |
|         ul.insertBefore(new_li, box_li);
 | |
|     }
 | |
| }
 | |
| function remove_searchtag(li_member, value, inputted_list)
 | |
| {
 | |
|     /*
 | |
|     Given a member of the same tag type as the one we intend to remove,
 | |
|     find the tag of interest and remove it from both the DOM and the
 | |
|     inputted_list.
 | |
| 
 | |
|     Sorry for the roundabout technique.
 | |
|     */
 | |
|     console.log("removing " + value);
 | |
|     var li = li_member.parentElement;
 | |
|     var ul = li.parentElement;
 | |
|     var lis = ul.children;
 | |
|     //console.log(lis);
 | |
|     for (var index = 0; index < lis.length; index += 1)
 | |
|     {
 | |
|         li = lis[index];
 | |
|         var span = li.children[0];
 | |
|         if (span.tagName != "SPAN")
 | |
|         {continue}
 | |
| 
 | |
|         var tagname = span.innerHTML;
 | |
|         if (tagname != value)
 | |
|         {continue}
 | |
| 
 | |
|         ul.removeChild(li);
 | |
|         splice_at = inputted_list.indexOf(tagname);
 | |
|         if (splice_at == -1)
 | |
|         {continue}
 | |
| 
 | |
|         inputted_list.splice(splice_at, 1);
 | |
|     }
 | |
| }
 | |
| function add_new_orderby()
 | |
| {
 | |
|     /* Called by the green + button */
 | |
|     var ul = document.getElementById("search_builder_orderby_ul");
 | |
|     if (ul.children.length >= 9)
 | |
|     {
 | |
|         /* 9 because there are only 9 sortable properties */
 | |
|         return;
 | |
|     }
 | |
|     var li = ul.children;
 | |
|     li = li[li.length - 2];
 | |
|     var clone_children = true;
 | |
|     var new_li = li.cloneNode(clone_children)
 | |
|     var button = document.getElementById("search_builder_orderby_newrow");
 | |
|     ul.insertBefore(new_li, button);
 | |
| }
 | |
| function orderby_remove_hook(button)
 | |
| {
 | |
|     /* Called by the red button next to orderby dropdowns */
 | |
|     var li = button.parentElement;
 | |
|     var ul = li.parentElement;
 | |
|     // 2 because keep 1 row and the adder button
 | |
|     if (ul.children.length>2)
 | |
|     {
 | |
|         /* You can't remove the only one left */
 | |
|         ul.removeChild(li);
 | |
|     }
 | |
| }
 | |
| function simplify_tagnames(tags)
 | |
| {
 | |
|     var new_tags = [];
 | |
|     for (var index = 0; index < tags.length; index += 1)
 | |
|     {
 | |
|         var tag = tags[index];
 | |
|         tag = tag.split(".");
 | |
|         tag = tag[tag.length - 1];
 | |
|         new_tags.push(tag);
 | |
|     }
 | |
|     return new_tags;
 | |
| }
 | |
| function submit_search()
 | |
| {
 | |
|     /*
 | |
|     Gather up all the form data and tags and compose the search URL
 | |
|     */
 | |
|     var url = window.location.origin + "/search";
 | |
|     var parameters = [];
 | |
|     var has_tag_params = false;
 | |
|     var musts = simplify_tagnames(inputted_musts).join(",");
 | |
|     if (musts) {parameters.push("tag_musts=" + musts); has_tag_params=true;}
 | |
| 
 | |
|     var mays = simplify_tagnames(inputted_mays).join(",");
 | |
|     if (mays) {parameters.push("tag_mays=" + mays); has_tag_params=true;}
 | |
| 
 | |
|     var forbids = simplify_tagnames(inputted_forbids).join(",");
 | |
|     if (forbids) {parameters.push("tag_forbids=" + forbids); has_tag_params=true;}
 | |
| 
 | |
|     var expression = document.getElementsByName("tag_expression")[0].value;
 | |
|     if (expression)
 | |
|     {
 | |
|         //expression = expression.replace(new RegExp(" ", 'g'), "-");
 | |
|         parameters.push("tag_expression=" + expression);
 | |
|         has_tag_params=true;
 | |
|     }
 | |
| 
 | |
|     var basic_inputs = document.getElementsByClassName("basic_param");
 | |
|     for (var index = 0; index < basic_inputs.length; index += 1)
 | |
|     {
 | |
|         var boxname = basic_inputs[index].name;
 | |
|         var box = document.getElementsByName(boxname)[0];
 | |
|         var value = box.value;
 | |
|         value = value.split("&").join("%26");
 | |
|         console.log(value);
 | |
|         if (PARAM_DEFAULTS[boxname] == value)
 | |
|         {
 | |
|             // Don't clutter url with default values.
 | |
|             continue;
 | |
|         }
 | |
|         if (boxname == "has_tags" && has_tag_params && value == "no")
 | |
|         {
 | |
|             /*
 | |
|             The user wants untagged only, but has tags in the search boxes?
 | |
|             Override to "tagged or untagged" and let the tag searcher handle it.
 | |
|             */
 | |
|             value = "";
 | |
|         }
 | |
|         if (value == "")
 | |
|         {
 | |
|             continue;
 | |
|         }
 | |
|         parameters.push(boxname + "=" + value);
 | |
|     }
 | |
| 
 | |
|     orderby_rows = document.getElementsByClassName("search_builder_orderby_li");
 | |
|     orderby_params = [];
 | |
|     for (var index = 0; index < orderby_rows.length; index += 1)
 | |
|     {
 | |
|         var row = orderby_rows[index];
 | |
|         var column = row.children[0].value;
 | |
|         var sorter = row.children[1].value;
 | |
|         orderby_params.push(column + "-" + sorter);
 | |
|     }
 | |
|     orderby_params = orderby_params.join(",");
 | |
|     if (orderby_params && orderby_params != "created-desc")
 | |
|     {
 | |
|         // Don't clutter url with default of created-desc
 | |
|         parameters.push("orderby=" + orderby_params);
 | |
|     }
 | |
| 
 | |
|     if (parameters.length > 0)
 | |
|     {
 | |
|         parameters = parameters.join("&");
 | |
|         parameters = "?" + parameters;
 | |
|         url = url + parameters;
 | |
|     }
 | |
|     console.log(url);
 | |
|     window.location.href = url;
 | |
|     return false;
 | |
| }
 | |
| function tags_on_this_page_hook()
 | |
| {
 | |
|     /*
 | |
|     This is hooked onto the tag objects listed under "Found on this page".
 | |
|     Clicking them will add it to your current search query under Musts
 | |
|     */
 | |
|     add_searchtag(
 | |
|         input_musts,
 | |
|         this.innerHTML,
 | |
|         inputted_musts,
 | |
|         "search_builder_musts_inputted"
 | |
|     );
 | |
|     return false;
 | |
| }
 | |
| function tag_input_hook(box, inputted_list, li_class)
 | |
| {
 | |
|     /*
 | |
|     Assigned to the input boxes for musts, mays, forbids.
 | |
|     Hitting Enter will add the resovled tag to the search form.
 | |
|     */
 | |
|     if (event.keyCode != 13)
 | |
|     {return;}
 | |
| 
 | |
|     if (!box.value)
 | |
|     {return;}
 | |
| 
 | |
|     var value = box.value.toLocaleLowerCase();
 | |
|     value = value.split(".");
 | |
|     value = value[value.length-1];
 | |
|     value = value.split("+")[0];
 | |
|     value = value.replace(new RegExp(" ", 'g'), "_");
 | |
|     value = value.replace(new RegExp("-", 'g'), "_");
 | |
|     if (!(value in QUALNAME_MAP))
 | |
|     {
 | |
|         return;
 | |
|     }
 | |
|     value = QUALNAME_MAP[value];
 | |
|     console.log(inputted_list);
 | |
|     add_searchtag(box, value, inputted_list, li_class)
 | |
|     box.value = "";
 | |
| }
 | |
| 
 | |
| 
 | |
| QUALNAME_MAP = {{qualname_map|safe}};
 | |
| var input_musts = document.getElementById("search_builder_musts_input");
 | |
| var input_mays = document.getElementById("search_builder_mays_input");
 | |
| var input_forbids = document.getElementById("search_builder_forbids_input");
 | |
| var input_expression = document.getElementById("search_builder_expression_input");
 | |
| 
 | |
| /* Prefix the form with the parameters from last search */
 | |
| var inputted_musts = [];
 | |
| var inputted_mays = [];
 | |
| var inputted_forbids = [];
 | |
| {% for tagtype in ["musts", "mays", "forbids"] %}
 | |
|     {% set key="tag_" + tagtype %}
 | |
|     {% if search_kwargs[key] %}
 | |
|     {% for tagname in search_kwargs[key] %}
 | |
|         inputted_{{tagtype}}.push("{{tagname}}");
 | |
|     {% endfor %}
 | |
|     {% endif %}
 | |
| {% endfor %}
 | |
| 
 | |
| /* Assign the click handler to "Tags on this page" results. */
 | |
| var found_on_page = document.getElementsByClassName("tag_object");
 | |
| for (var index = 0; index < found_on_page.length; index += 1)
 | |
| {
 | |
|     var tag_object = found_on_page[index];
 | |
|     if (tag_object.tagName != "A")
 | |
|     {continue}
 | |
| 
 | |
|     tag_object.onclick = tags_on_this_page_hook;
 | |
|     
 | |
| }
 | |
| 
 | |
| input_musts.onkeydown = function(){tag_input_hook(this, inputted_musts, "search_builder_musts_inputted")};
 | |
| input_mays.onkeydown = function(){tag_input_hook(this, inputted_mays, "search_builder_mays_inputted")};
 | |
| input_forbids.onkeydown = function(){tag_input_hook(this, inputted_forbids, "search_builder_forbids_inputted")};
 | |
| bind_box_to_button(input_expression, document.getElementById("search_go_button"));
 | |
| </script>
 | |
| </html> |