123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- /**
- * @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author John Molakvoæ <skjnldsv@protonmail.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- import _ from 'underscore'
- import OC from './index'
- /**
- * Utility class for the history API,
- * includes fallback to using the URL hash when
- * the browser doesn't support the history API.
- *
- * @namespace OC.Util.History
- */
- export default {
- _handlers: [],
- /**
- * Push the current URL parameters to the history stack
- * and change the visible URL.
- * Note: this includes a workaround for IE8/IE9 that uses
- * the hash part instead of the search part.
- *
- * @param {object | string} params to append to the URL, can be either a string
- * or a map
- * @param {string} [url] URL to be used, otherwise the current URL will be used,
- * using the params as query string
- * @param {boolean} [replace=false] whether to replace instead of pushing
- */
- _pushState(params, url, replace) {
- let strParams
- if (typeof (params) === 'string') {
- strParams = params
- } else {
- strParams = OC.buildQueryString(params)
- }
- if (window.history.pushState) {
- url = url || location.pathname + '?' + strParams
- // Workaround for bug with SVG and window.history.pushState on Firefox < 51
- // https://bugzilla.mozilla.org/show_bug.cgi?id=652991
- const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
- if (isFirefox && parseInt(navigator.userAgent.split('/').pop()) < 51) {
- const patterns = document.querySelectorAll('[fill^="url(#"], [stroke^="url(#"], [filter^="url(#invert"]')
- for (let i = 0, ii = patterns.length, pattern; i < ii; i++) {
- pattern = patterns[i]
- // eslint-disable-next-line no-self-assign
- pattern.style.fill = pattern.style.fill
- // eslint-disable-next-line no-self-assign
- pattern.style.stroke = pattern.style.stroke
- pattern.removeAttribute('filter')
- pattern.setAttribute('filter', 'url(#invert)')
- }
- }
- if (replace) {
- window.history.replaceState(params, '', url)
- } else {
- window.history.pushState(params, '', url)
- }
- } else {
- // use URL hash for IE8
- window.location.hash = '?' + strParams
- // inhibit next onhashchange that just added itself
- // to the event queue
- this._cancelPop = true
- }
- },
- /**
- * Push the current URL parameters to the history stack
- * and change the visible URL.
- * Note: this includes a workaround for IE8/IE9 that uses
- * the hash part instead of the search part.
- *
- * @param {object | string} params to append to the URL, can be either a string or a map
- * @param {string} [url] URL to be used, otherwise the current URL will be used, using the params as query string
- */
- pushState(params, url) {
- this._pushState(params, url, false)
- },
- /**
- * Push the current URL parameters to the history stack
- * and change the visible URL.
- * Note: this includes a workaround for IE8/IE9 that uses
- * the hash part instead of the search part.
- *
- * @param {object | string} params to append to the URL, can be either a string
- * or a map
- * @param {string} [url] URL to be used, otherwise the current URL will be used,
- * using the params as query string
- */
- replaceState(params, url) {
- this._pushState(params, url, true)
- },
- /**
- * Add a popstate handler
- *
- * @param {Function} handler handler
- */
- addOnPopStateHandler(handler) {
- this._handlers.push(handler)
- },
- /**
- * Parse a query string from the hash part of the URL.
- * (workaround for IE8 / IE9)
- *
- * @return {string}
- */
- _parseHashQuery() {
- const hash = window.location.hash
- const pos = hash.indexOf('?')
- if (pos >= 0) {
- return hash.substr(pos + 1)
- }
- if (hash.length) {
- // remove hash sign
- return hash.substr(1)
- }
- return ''
- },
- _decodeQuery(query) {
- return query.replace(/\+/g, ' ')
- },
- /**
- * Parse the query/search part of the URL.
- * Also try and parse it from the URL hash (for IE8)
- *
- * @return {object} map of parameters
- */
- parseUrlQuery() {
- const query = this._parseHashQuery()
- let params
- // try and parse from URL hash first
- if (query) {
- params = OC.parseQueryString(this._decodeQuery(query))
- }
- // else read from query attributes
- params = _.extend(params || {}, OC.parseQueryString(this._decodeQuery(location.search)))
- return params || {}
- },
- _onPopState(e) {
- if (this._cancelPop) {
- this._cancelPop = false
- return
- }
- let params
- if (!this._handlers.length) {
- return
- }
- params = (e && e.state)
- if (_.isString(params)) {
- params = OC.parseQueryString(params)
- } else if (!params) {
- params = this.parseUrlQuery() || {}
- }
- for (let i = 0; i < this._handlers.length; i++) {
- this._handlers[i](params)
- }
- },
- }
|