: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
if (handler.route.test(fragment)) {
handler.callback(fragment);
// Save a fragment into the hash history, or replace the URL state if the
// 'replace' option is passed. You are responsible for properly URL-encoding
// the fragment in advance.
// The options object can contain `trigger: true` if you wish to have the
// route callback be fired (not usually desirable), or `replace: true`, if
// you wish to modify the current URL without adding an entry to the history.
navigate: function(fragment, options) {
if (!History.started) return false;
if (!options || options === true) options = {trigger: !!options};
// Normalize the fragment.
fragment = this.getFragment(fragment || '');
// Strip trailing slash on the root unless _trailingSlash is true
var rootPath = this.root;
if (!this._trailingSlash && (fragment === '' || fragment.charAt(0) === '?')) {
rootPath = rootPath.slice(0, -1) || '/';
var url = rootPath + fragment;
// Strip the fragment of the query and hash for matching.
fragment = fragment.replace(pathStripper, '');
var decodedFragment = this.decodeFragment(fragment);
if (this.fragment === decodedFragment) return;
this.fragment = decodedFragment;
// If pushState is available, we use it to set the fragment as a real URL.
if (this._usePushState) {
this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
// If hash changes haven't been explicitly disabled, update the hash
// fragment to store history.
} else if (this._wantsHashChange) {
this._updateHash(this.location, fragment, options.replace);
if (this.iframe && fragment !== this.getHash(this.iframe.contentWindow)) {
var iWindow = this.iframe.contentWindow;
// Opening and closing the iframe tricks IE7 and earlier to push a
// history entry on hash-tag change. When replace is true, we don't
iWindow.document.close();
this._updateHash(iWindow.location, fragment, options.replace);
// If you've told us that you explicitly don't want fallback hashchange-
// based history, then `navigate` becomes a page refresh.
return this.location.assign(url);
if (options.trigger) return this.loadUrl(fragment);
// Update the hash location, either replacing the current entry, or adding
// a new one to the browser history.
_updateHash: function(location, fragment, replace) {
var href = location.href.replace(/(javascript:|#).*$/, '');
location.replace(href + '#' + fragment);
// Some browsers require that `hash` contains a leading #.
location.hash = '#' + fragment;
// Create the default Backbone.history.
Backbone.history = new History;
// Helper function to correctly set up the prototype chain for subclasses.
// Similar to `goog.inherits`, but uses a hash of prototype properties and
// class properties to be extended.
var extend = function(protoProps, staticProps) {
// The constructor function for the new subclass is either defined by you
// (the "constructor" property in your `extend` definition), or defaulted
// by us to simply call the parent constructor.
if (protoProps && _.has(protoProps, 'constructor')) {
child = protoProps.constructor;
child = function(){ return parent.apply(this, arguments); };
// Add static properties to the constructor function, if supplied.
_.extend(child, parent, staticProps);
// Set the prototype chain to inherit from `parent`, without calling
// `parent`'s constructor function and add the prototype properties.
child.prototype = _.create(parent.prototype, protoProps);
child.prototype.constructor = child;
// Set a convenience property in case the parent's prototype is needed
child.__super__ = parent.prototype;
// Set up inheritance for the model, collection, router, view and history.
Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
// Throw an error when a URL is needed, and none is supplied.
var urlError = function() {
throw new Error('A "url" property or function must be specified');
// Wrap an optional error callback with a fallback error event.
var wrapError = function(model, options) {
var error = options.error;
options.error = function(resp) {
if (error) error.call(options.context, model, resp, options);
model.trigger('error', model, resp, options);