Source

hashify.me / src / location.coffee

{addEvent, decode, publish, subscribe} = Hashify.utils

directives = [
  # name,  in longest query
  ['mode:presentation', yes]
  ['raw:yes',            no]
]

class Query
  constructor: (params) ->
    @params = {}
    @params[param] = 1 for param in params

  clone: ->
    new Query @params

  contains: (param) ->
    param of @params

  toString: ->
    params = (name for [name] in directives when @contains name).join(';')
    params and '?' + params

subscribe 'pre:hashchange', (args...) ->
  args unless /^unpack:/.test args[0]

subscribe 'hashchange', (hash, options = {}) ->
  publish 'textchange', decode hash
  path = '/' + hash + (Hashify.location.components().query or '')
  if window.history?.pushState
    method = if options.save then 'pushState' else 'replaceState'
    history[method] null, null, path
  else
    path = '/#!' + path
    # Since `location.replace` overwrites the current history entry,
    # saving a location to history is not simply a matter of calling
    # `location.assign`. Instead, we must create a new history entry
    # and immediately overwrite it.

    # Update current history entry.
    location.replace path

    if options.save
      # Create a new history entry (to save the current one).
      location.hash = '#!/'
      # Update the new history entry (to reinstate the hash).
      location.replace path

components = ->
  {pathname, search, hash} = location
  if match = /^#!\/([^?]*)(\?.*)?$/.exec(hash)
    hash: match[1], query: match[2]
  else
    hash: pathname.substr(1), query: search

addEvent window, 'popstate', ->
  publish 'hashchange', components().hash

longest = new Query (name for [name, include] in directives when include)

Hashify.location =
  components: ->
    {hash, query} = components()
    query = new Query query and query.replace(/^\?/, '').split(';') or []
    {hash, query}
  longestQueryString: "#{longest}"
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.