Skip to content

Commit

Permalink
Merge df80a1d into 4c45bc0
Browse files Browse the repository at this point in the history
  • Loading branch information
aphillipo committed Jul 18, 2017
2 parents 4c45bc0 + df80a1d commit a2c50a7
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 51 deletions.
10 changes: 9 additions & 1 deletion assets/js/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// ------------

import $ from 'jquery'
import {start as search} from './search'
import {start as search, popstateHandler, getParameterByName} from './search'
import * as helpers from './helpers'

import sidebarItemsTemplate from './templates/sidebar-items.handlebars'
Expand Down Expand Up @@ -103,6 +103,14 @@ function addEventListeners () {
$('.sidebar-search .icon-search').on('click', function (e) {
search()
})

$(window).on('popstate', popstateHandler)

// if the search stub is refreshed or loaded perform the search.
if (window.location.pathname === '/search.html') {
const qs = getParameterByName('q')
search(qs, false)
}
}

function identifyCurrentHash () {
Expand Down
140 changes: 90 additions & 50 deletions assets/js/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import resultsTemplate from './templates/search-results.handlebars'
const $content = $('.content-inner')
const $input = $('.sidebar-search input')
const $sidebarItems = $('#full-list li')
var $results
let $results
let $oldContent
let searchCount = 0

// Local Methods
// -------------
Expand Down Expand Up @@ -79,7 +81,29 @@ export function findIn (elements, matcher) {
}).filter(cleaner)
}

function search (nodes, value) {
export function getParameterByName (name, url) {
if (!url) {
url = window.location.href
}
const param = name.replace(/[\[\]]/g, '\\$&')
const regex = new RegExp('[?&]' + param + '(=([^&#]*)|&|#|$)')
const results = regex.exec(url)
if (!results) {
return null
}
if (!results[2]) {
return ''
}
return decodeURIComponent(results[2].replace(/\+/g, ' '))
}

function pushLevel (levels, searchEntity, name) {
if (searchEntity.length > 0) {
levels.push({name: name, results: searchEntity})
}
}

function search (nodes, value, addHistory) {
var safeVal = new RegExp(helpers.escapeText(value), 'i')

var levels = []
Expand All @@ -89,33 +113,18 @@ function search (nodes, value) {
var protocols = findIn(nodes.protocols, safeVal)
var tasks = findIn(nodes.tasks, safeVal)

if (modules.length > 0) {
levels.push({
name: 'Modules',
results: modules
})
// sometimes we need to stop adding to the history if it already exists.
if (addHistory !== false) {
// we use this to track searches that are in the history
searchCount++
history.pushState({searchValue: value}, 'Searching for ' + value, '/search.html?q=' + value)
}

if (exceptions.length > 0) {
levels.push({
name: 'Exceptions',
results: exceptions
})
}

if (protocols.length > 0) {
levels.push({
name: 'Protocols',
results: protocols
})
}

if (tasks.length > 0) {
levels.push({
name: 'Mix Tasks',
results: tasks
})
}
// add to the results
pushLevel(levels, modules, 'Modules')
pushLevel(levels, exceptions, 'Exceptions')
pushLevel(levels, protocols, 'Protocols')
pushLevel(levels, tasks, 'Mix Tasks')

if ($results) {
$results.remove()
Expand All @@ -127,49 +136,80 @@ function search (nodes, value) {
empty: levels.length === 0
}))

var $oldContent = $content.children()
$oldContent = $content.children()
$oldContent.hide()
$content.append($results)

// Auto-hide Menu if on Mobile device
window.screen.width < breakpoint ? closeSidebar() : null

function closeResults (e) {
var event = e || window.event
var $hashElement = document.getElementById(helpers.getLocationHash())
if (typeof event === 'object' && event !== null) {
if (event.metaKey || event.shiftKey || event.altKey ||
event.ctrlKey || event.button === 1 || event.button === 2) {
return
}
}

$results.remove()
$oldContent.fadeIn()
if ($hashElement && $hashElement.scrollIntoView) {
$hashElement.scrollIntoView()
}
}

// we use history to close the search
$results.find('.close-search').on('click', function (e) {
e.preventDefault()
closeResults(e)
history.go(-searchCount)
})

$.merge($results.find('a'), $sidebarItems).on('click', closeResults)
// every other link closes the search
$.merge($results.find('a').not('.close-search'), $sidebarItems).on('click', function (e) {
closeResults(e, false)
})

$results.fadeIn(function () {
// Scroll the container with all elements
$content.parent().scrollTop(0)
})
}

function closeResults (e, removeResults) {
var event = e || window.event
var $hashElement = document.getElementById(helpers.getLocationHash())
if (typeof event === 'object' && event !== null) {
if (event.metaKey || event.shiftKey || event.altKey ||
event.ctrlKey || event.button === 1 || event.button === 2) {
return
}
}
if ($hashElement && $hashElement.scrollIntoView) {
$hashElement.scrollIntoView()
}

if (removeResults !== false) {
// clear the search bar if someone closes results.
$input.val('')
if ($results) {
$results.remove()
}
if ($oldContent) {
$oldContent.fadeIn()
}
}
}

// Public Methods
// --------------

export function start () {
var searchVal = $input.val()

export function start (val, addHistory) {
var searchVal = val || $input.val()
if (searchVal === '') return
search(sidebarNodes, searchVal, addHistory)
}

export function popstateHandler (event) {
if (searchCount > 0) {
searchCount--
}

search(sidebarNodes, searchVal)
if (event.originalEvent.state == null) {
// NOTE: for reasons only known to the browser makers we need to reload here,
// on back after navigating away the page (clicking a result in the search)
// there is no original page content i.e. all that was display none is gone
// note this doesn't happen in Safari, just FF and Chrome.
document.location.reload(true)
} else if ('searchValue' in event.originalEvent.state) {
// when we have a searchValue, show the search but clearly don't push a history state
var searchValue = event.originalEvent.state.searchValue
$input.val(searchValue) // set the search box to the searchValue for this state
search(sidebarNodes, searchValue, false) // no history here, we already have one
}
}
9 changes: 9 additions & 0 deletions lib/ex_doc/formatter/html.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ defmodule ExDoc.Formatter.HTML do
generate_sidebar_items(nodes_map, extras, config) ++
generate_extras(nodes_map, extras, config) ++
generate_logo(assets_dir, config) ++
generate_search(nodes_map, config) ++
generate_not_found(nodes_map, config) ++
generate_list(nodes_map.modules, nodes_map, config) ++
generate_list(nodes_map.exceptions, nodes_map, config) ++
Expand Down Expand Up @@ -90,6 +91,14 @@ defmodule ExDoc.Formatter.HTML do
[filename]
end

defp generate_search(nodes_map, config) do
filename = "search.html"
config = set_canonical_url(config, filename)
content = Templates.search_template(config, nodes_map)
File.write!("#{config.output}/#{filename}", content)
[filename]
end

defp generate_sidebar_items(nodes_map, extras, config) do
content = Templates.create_sidebar_items(nodes_map, extras)

Expand Down
1 change: 1 addition & 0 deletions lib/ex_doc/formatter/html/templates.ex
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ defmodule ExDoc.Formatter.HTML.Templates do
api_reference_entry_template: [:module_node],
api_reference_template: [:config, :nodes_map],
extra_template: [:config, :title, :nodes_map, :content],
search_template: [:config, :nodes_map],
sidebar_template: [:config, :nodes_map],
summary_template: [:name, :nodes],
summary_item_template: [:module_node],
Expand Down
4 changes: 4 additions & 0 deletions lib/ex_doc/formatter/html/templates/search_template.eex
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<%= head_template(config, %{title: "Search", type: :extra}) %>
<%= sidebar_template(config, nodes_map) %>

<%= footer_template(config) %>
8 changes: 8 additions & 0 deletions priv/ex_doc/formatter/html/assets/dist/app-a2bac5db17.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

0 comments on commit a2c50a7

Please sign in to comment.