node模块warning.js
'use strict'; var __DEV__ = process.env.NODE_ENV !== 'production'; var warning = function() {}; if (__DEV__) { // warning(condition,format,args) 开发环境下,condition为否值时,使用args替换报错字符串模板format输出 warning = function(condition, format, args) { var len = arguments.length; args = new Array(len > 2 ? len - 2 : 0); for (var key = 2; key < len; key++) { args[key - 2] = arguments[key]; } if (format === undefined) { throw new Error( '`warning(condition, format, ...args)` requires a warning ' + 'message argument' ); } // 报错字符串模板format内容不充分 if (format.length < 10 || (/^[s\W]*$/).test(format)) { throw new Error( 'The warning format should be able to uniquely identify this ' + 'warning. Please, use a more descriptive format than: ' + format ); } if (!condition) { var argIndex = 0; var message = 'Warning: ' + format.replace(/%s/g, function() { return args[argIndex++]; }); if (typeof console !== 'undefined') { console.error(message); } try { throw new Error(message); } catch(x) {} } }; } module.exports = warning;
node模块invariant.js
'use strict'; var NODE_ENV = process.env.NODE_ENV; // invariant(condition,format,a,b,c,d,e,f),condition为否值时,以a,b,c,d,e,f替换报错模板字符串format,抛出错误 var invariant = function(condition, format, a, b, c, d, e, f) { // 开发环境下模板字符串format缺省,报错 if (NODE_ENV !== 'production') { if (format === undefined) { throw new Error('invariant requires an error message argument'); } } if (!condition) { var error; // 生产环境下模板字符串format缺省,报错 if (format === undefined) { error = new Error( 'Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.' ); } else { var args = [a, b, c, d, e, f]; var argIndex = 0; error = new Error( format.replace(/%s/g, function() { return args[argIndex++]; }) ); error.name = 'Invariant Violation'; } error.framesToPop = 1; throw error; } }; module.exports = invariant;
ExecutionEnvironment.js侦测是否浏览器环境,可操作dom节点
DomUtils.js绑定事件、浏览器能力检测
runTransitionHook.js执行钩子函数
AsyncUtils.js异步流程处理
Action.js约定location.action可赋予的值,location.action影响allKeys跳转路径记录
PathUtils.js路径操作相关工具函数
LocationUtils.js通过路径和存储state数据创建location路径数据对象,比较两个路径数据对象是否相同
/*---------- ExecutionEnvironment.js模块 -----------*/ 'use strict'; // 判断平台是否为浏览器环境,可以操作dom节点 exports.__esModule = true; var canUseDOM = exports.canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement); /*---------- DomUtils.js模块 -----------*/ 'use strict'; exports.__esModule = true; // dom节点绑点、移除函数方法封装 var addEventListener = exports.addEventListener = function addEventListener(node, event, listener) { return node.addEventListener ? node.addEventListener(event, listener, false) : node.attachEvent('on' + event, listener); }; var removeEventListener = exports.removeEventListener = function removeEventListener(node, event, listener) { return node.removeEventListener ? node.removeEventListener(event, listener, false) : node.detachEvent('on' + event, listener); }; // 能力检测,判断浏览器是否支持HTML5 history API var supportsHistory = exports.supportsHistory = function supportsHistory() { var ua = window.navigator.userAgent; if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) return false; return window.history && 'pushState' in window.history; }; // 能力检测,判断window.history.go(n)方法更新哈希路径是否会导致页面重新加载 var supportsGoWithoutReloadUsingHash = exports.supportsGoWithoutReloadUsingHash = function supportsGoWithoutReloadUsingHash() { return window.navigator.userAgent.indexOf('Firefox') === -1; }; // 能力检测,判断哈希路径改变时是否会触发popstate事件 var supportsPopstateOnHashchange = exports.supportsPopstateOnHashchange = function supportsPopstateOnHashchange() { return window.navigator.userAgent.indexOf('Trident') === -1; }; /*---------- runTransitionHook.js模块 -----------*/ 'use strict'; exports.__esModule = true; // node模块;warning(condition,format,args) 开发环境下,condition为否值时,使用args替换报错字符串模板format输出 // _warning2.default引用_warning,即node模块warning var _warning = require('warning'); var _warning2 = _interopRequireDefault(_warning); // obj为history模块内建模块(函数),原样输出;否则将函数挂载在default方法上 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // 执行hook(location),callback为hook函数执行完成后的回调 // 执行hook(location,callback),callback在hook函数内部调用,hook不能返回真值 var runTransitionHook = function runTransitionHook(hook, location, callback) { var result = hook(location, callback); // hook为函数时,hook.length为函数声明时传参的个数 if (hook.length < 2) { callback(result); } else { // hook接受两个参数,即callback在hook中调用,result不能为真值 process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(result === undefined, 'You should not "return" in a transition hook with a callback argument; ' + 'call the callback instead') : void 0; } }; exports.default = runTransitionHook; /*---------- AsyncUtils.js模块 -----------*/ "use strict"; exports.__esModule = true; // 设定以高阶函数work(currentTurn,next,done)操作长度为turns的数组(纯数据或函数集) // turns迭代最大次数,work(currentTurn++,next,done)迭代执行函数,callback回调 var loopAsync = exports.loopAsync = function loopAsync(turns, work, callback) { var currentTurn = 0, isDone = false;// 结束迭代标识 var isSync = false,// 异步的work执行过程中标识,使用next函数参数执行work hasNext = false, doneArgs = void 0; // 主动调用done函数结束迭代,done函数不在延时后调用,执行callback回调 var done = function done() { // done函数接受的参数,作为callback回调的参数 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } isDone = true; // done函数同步调用,isSync仍为true,callback回调在next函数中执行,参数为doneArgs if (isSync) { doneArgs = args; return; } // 执行callback回调 callback.apply(undefined, args); }; var next = function next() { if (isDone) return; hasNext = true; if (isSync) return;// 异步work执行过程中,跳出 isSync = true; // while循环除作为条件判断以外,没有实质性意义 while (!isDone && currentTurn < turns && hasNext) { hasNext = false; // next同步调用时,hasNext直接被赋值为true,同时isSync仍为true,不进入while循环; // next异步延时调用,hasNext仍是false,不进入while循环 work(currentTurn++, next, done); } isSync = false; // done函数同步调用时,执行callback回调 if (isDone) { callback.apply(undefined, doneArgs); return; } // 所有迭代均完成,执行回调 if (currentTurn >= turns && hasNext) { isDone = true; callback(); } }; next(); }; /*---------- Action.js模块 -----------*/ 'use strict'; exports.__esModule = true; // 作为location.action的值,histroy对象中使用push方法将在allKeys中添加一条路径记录 var PUSH = exports.PUSH = 'PUSH'; // 作为location.action的值,histroy对象中使用replace方法将在allKeys中替换一条路径记录 var REPLACE = exports.REPLACE = 'REPLACE'; // 作为location.action的默认值,用户手动变更页面路径,allKeys不作任何处理 var POP = exports.POP = 'POP'; /*---------- PathUtils.js模块 -----------*/ 'use strict'; exports.__esModule = true; exports.createPath = exports.parsePath = exports.getQueryStringValueFromPath = exports.stripQueryStringValueFromPath = exports.addQueryStringValueToPath = undefined; // node模块;warning(condition,format,args) 开发环境下,condition为否值时,使用args替换报错字符串模板format输出 // _warning2.default引用_warning,即node模块warning var _warning = require('warning'); var _warning2 = _interopRequireDefault(_warning); // obj为history模块内建模块(函数),原样输出;否则将函数挂载在default方法上 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // path下查询字符串search部分添加key+"="+value,重新拼接路径并返回 var addQueryStringValueToPath = exports.addQueryStringValueToPath = function addQueryStringValueToPath(path, key, value) { var _parsePath = parsePath(path); var pathname = _parsePath.pathname; var search = _parsePath.search; var hash = _parsePath.hash; return createPath({ pathname: pathname, search: search + (search.indexOf('?') === -1 ? '?' : '&') + key + '=' + value, hash: hash }); }; // path下查询字符串search中含有key键值,将search转化为"?"或"&",构建新的路径字符串 var stripQueryStringValueFromPath = exports.stripQueryStringValueFromPath = function stripQueryStringValueFromPath(path, key) { // 将不包含协议名的路径path转化对象形式,对象中含域名path、查询字符串search、哈希路径hash var _parsePath2 = parsePath(path); var pathname = _parsePath2.pathname; var search = _parsePath2.search; var hash = _parsePath2.hash; return createPath({ pathname: pathname, search: search.replace(new RegExp('([?&])' + key + '=[a-zA-Z0-9]+(&?)'), function (match, prefix, suffix) { return prefix === '?' ? prefix : suffix; }), hash: hash }); }; // 获取路径path下查询字符串search中,key键的值 var getQueryStringValueFromPath = exports.getQueryStringValueFromPath = function getQueryStringValueFromPath(path, key) { // 将不包含协议名的路径path转化对象形式,对象中含域名path、查询字符串search、哈希路径hash var _parsePath3 = parsePath(path); var search = _parsePath3.search; var match = search.match(new RegExp('[?&]' + key + '=([a-zA-Z0-9]+)')); return match && match[1]; }; // 将https://、http://、或//起始的路径转化为空字符串,否则原样输出 var extractPath = function extractPath(string) { var match = string.match(/^(https?:)?\/\/[^\/]*/); return match == null ? string : string.substring(match[0].length); }; // 将不包含协议名的路径path转化对象形式,对象中含路径path、查询字符串search、哈希路径hash var parsePath = exports.parsePath = function parsePath(path) { var pathname = extractPath(path); var search = ''; var hash = ''; // 校验传参path是否以https://、http://、或//起始 process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(path === pathname, 'A path must be pathname + search + hash only, not a full URL like "%s"', path) : void 0; // 获取路径中"#"起始的哈希部分hash var hashIndex = pathname.indexOf('#'); if (hashIndex !== -1) { hash = pathname.substring(hashIndex); pathname = pathname.substring(0, hashIndex); } // 获取路径中以"?"起始的查询字符串部分search // 路径以pathname获取 var searchIndex = pathname.indexOf('?'); if (searchIndex !== -1) { search = pathname.substring(searchIndex); pathname = pathname.substring(0, searchIndex); } if (pathname === '') pathname = '/'; return { pathname: pathname, search: search, hash: hash }; }; // 将对象形式的路径拼接成路径字符串后返回 var createPath = exports.createPath = function createPath(location) { if (location == null || typeof location === 'string') return location; var basename = location.basename; var pathname = location.pathname; var search = location.search; var hash = location.hash; var path = (basename || '') + pathname; if (search && search !== '?') path += search; if (hash) path += hash; return path; }; /*---------- LocationUtils.js模块 -----------*/ 'use strict'; exports.__esModule = true; exports.locationsAreEqual = exports.statesAreEqual = exports.createLocation = exports.createQuery = undefined; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; // 类似jquery.extend,将带靠背对象浅拷贝给目标对象 var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // node模块;invariant(condition,format,a,b,c,d,e,f),condition为否值时,以a,b,c,d,e,f替换报错模板字符串format,抛出错误 // _invariant2.default引用_invariant,即node模块invariant var _invariant = require('invariant'); var _invariant2 = _interopRequireDefault(_invariant); // node模块;warning(condition,format,args) 开发环境下,condition为否值时,使用args替换报错字符串模板format输出 // _warning2.default引用_warning,即node模块warning var _warning = require('warning'); var _warning2 = _interopRequireDefault(_warning); // 路径操作工具函数集 var _PathUtils = require('./PathUtils'); // location.action允许的值 var _Actions = require('./Actions'); // obj为history模块内建模块(函数),原样输出;否则将函数挂载在default方法上 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // 使用props创建对象 var createQuery = exports.createQuery = function createQuery(props) { return _extends(Object.create(null), props); }; // createLocation(obj={pathname,search,hash,state}|path,action=undefined,key) // 将location数据转化为对象形式输出{pathname,search,hash,state,action,key} var createLocation = exports.createLocation = function createLocation() { var input = arguments.length <= 0 || arguments[0] === undefined ? '/' : arguments[0]; var action = arguments.length <= 1 || arguments[1] === undefined ? _Actions.POP : arguments[1]; var key = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2]; // _PathUtils.parsePath将不包含协议名的路径path转化对象形式,对象中含路径path、查询字符串search、哈希路径hash var object = typeof input === 'string' ? (0, _PathUtils.parsePath)(input) : input; process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(!object.path, 'Location descriptor objects should have a `pathname`, not a `path`.') : void 0; var pathname = object.pathname || '/'; var search = object.search || ''; var hash = object.hash || ''; var state = object.state; return { pathname: pathname, search: search, hash: hash, state: state, action: action, key: key }; }; // 是否date对象 var isDate = function isDate(object) { return Object.prototype.toString.call(object) === '[object Date]'; }; // 判断变量a、b内容是否相同 var statesAreEqual = exports.statesAreEqual = function statesAreEqual(a, b) { if (a === b) return true; var typeofA = typeof a === 'undefined' ? 'undefined' : _typeof(a); var typeofB = typeof b === 'undefined' ? 'undefined' : _typeof(b); if (typeofA !== typeofB) return false; !(typeofA !== 'function') ? process.env.NODE_ENV !== 'production' ? (0, _invariant2.default)(false, 'You must not store functions in location state') : (0, _invariant2.default)(false) : void 0; if (typeofA === 'object') { !!(isDate(a) && isDate(b)) ? process.env.NODE_ENV !== 'production' ? (0, _invariant2.default)(false, 'You must not store Date objects in location state') : (0, _invariant2.default)(false) : void 0; if (!Array.isArray(a)) { var keysofA = Object.keys(a); var keysofB = Object.keys(b); return keysofA.length === keysofB.length && keysofA.every(function (key) { return statesAreEqual(a[key], b[key]); }); } return Array.isArray(b) && a.length === b.length && a.every(function (item, index) { return statesAreEqual(item, b[index]); }); } return false; }; // 判断a、b两个location数据对象是否相同 var locationsAreEqual = exports.locationsAreEqual = function locationsAreEqual(a, b) { return a.key === b.key && a.pathname === b.pathname && a.search === b.search && a.hash === b.hash && statesAreEqual(a.state, b.state); };
DomStateStorage.js使用window.sessionStorage存储{key:state}数据,state可以是后台返回的json数据,key由history生成,通过查询字符串location.search(hashHistory情形通过哈希路径部分获取location.search)读取
'use strict'; exports.__esModule = true; exports.readState = exports.saveState = undefined; // node模块;warning(condition,format,args) 开发环境下,condition为否值时,使用args替换报错字符串模板format输出 // _warning2.default引用_warning,即node模块warning var _warning = require('warning'); var _warning2 = _interopRequireDefault(_warning); // obj为history模块内建模块(函数),原样输出;否则将函数挂载在default方法上 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var QuotaExceededErrors = { QuotaExceededError: true, QUOTA_EXCEEDED_ERR: true }; var SecurityErrors = { SecurityError: true }; var KeyPrefix = '@@History/'; var createKey = function createKey(key) { return KeyPrefix + key; }; // 使用window.sessionStorage(当前页面有效)存储location.state数据,或者移除数据 var saveState = exports.saveState = function saveState(key, state) { if (!window.sessionStorage) { process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(false, '[history] Unable to save state; sessionStorage is not available') : void 0; return; } try { if (state == null) { window.sessionStorage.removeItem(createKey(key)); } else { window.sessionStorage.setItem(createKey(key), JSON.stringify(state)); } } catch (error) { if (SecurityErrors[error.name]) { process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(false, '[history] Unable to save state; sessionStorage is not available due to security settings') : void 0; return; } if (QuotaExceededErrors[error.name] && window.sessionStorage.length === 0) { process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(false, '[history] Unable to save state; sessionStorage is not available in Safari private mode') : void 0; return; } throw error; } }; // 读取window.sessionStorage(当前页面有效)存储的location.state数据 var readState = exports.readState = function readState(key) { var json = void 0; try { json = window.sessionStorage.getItem(createKey(key)); } catch (error) { if (SecurityErrors[error.name]) { // Blocking cookies in Chrome/Firefox/Safari throws SecurityError on any // attempt to access window.sessionStorage. process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(false, '[history] Unable to read state; sessionStorage is not available due to security settings') : void 0; return undefined; } } if (json) { try { return JSON.parse(json); } catch (error) { } } return undefined; };
history.js创建基本路径跳转、绑定函数、添加回调、获取location数据操作,createHashHistory、createBrowserHistory、createMemoryHistory在此基础上拓展功能
'use strict'; exports.__esModule = true; // loopAsync(turns,work,callback)设定以高阶函数work(currentTurn,next,done)操作长度为turns的数组(纯数据或函数集) var _AsyncUtils = require('./AsyncUtils'); // 路径操作工具函数集 var _PathUtils = require('./PathUtils'); // runTransitionHook(hook,location,callback) // 执行hook(location),callback为hook函数执行完成后的回调 // 执行hook(location,callback),callback在hook函数内部调用,hook不能返回真值 var _runTransitionHook = require('./runTransitionHook'); var _runTransitionHook2 = _interopRequireDefault(_runTransitionHook); // location.action允许的值 var _Actions = require('./Actions'); // 创建、比较location数据对象方法集 var _LocationUtils = require('./LocationUtils'); // obj为history模块内建模块(函数),原样输出;否则将函数挂载在default方法上 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // 创建histroy对象,createHashHistory、createBroswerHistory中调用 // 创建变更页面路径到更新location数据到执行绑点函数的一般方法 var createHistory = function createHistory() { // 首参有效 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; // 获取当期的路径数据 // hashHistroy情形,路径数据为{pathname,search,hash,state,action,key},pathname、search、hash都来自哈希路径 var getCurrentLocation = options.getCurrentLocation; // getUserConfirmation(message,callback) 在callback回调中定制执行window.confirm(message) var getUserConfirmation = options.getUserConfirmation; // 路径重新赋值 // hashHistroy情形,哈希路径重新赋值,并使用window.sessionStorage存储{[key]:state}形式的location哈希路径数据 var pushLocation = options.pushLocation; // 路径替换 // hashHistroy情形,替换哈希路径,并使用window.sessionStorage存储{[key]:state}形式的location哈希路径数据 var replaceLocation = options.replaceLocation; // 内部调用window.history.go处理传参 var go = options.go; var keyLength = options.keyLength; // 当前的location数据{pathname,search,hash,state,action,key} var currentLocation = void 0; // 待更新的location数据{pathname,search,hash,state,action,key} var pendingLocation = void 0; // 页面路径改变后执行的前置钩子函数 var beforeListeners = []; // 页面路径改变后执行的后置钩子函数 var listeners = []; // 以数组记录各次路径改变,便于go函数计算跳转页面 var allKeys = []; // 当前location数据currentLocation.key在allKeys中的位置值 var getCurrentIndex = function getCurrentIndex() { if (pendingLocation && pendingLocation.action === _Actions.POP) return allKeys.indexOf(pendingLocation.key); if (currentLocation) return allKeys.indexOf(currentLocation.key); return -1; }; // nextLocation.action为_Actions.PUSH时,allKeys添加nextLocation.key,触发listeners回调 // nextLocation.action为_Actions.REPLACE时,allKeys替换currentLocation.key为nextLocation.key,触发listeners回调 // nextLocation.action为_Actions.POP时,不对allKeys进行任何操作,触发listeners回调 var updateLocation = function updateLocation(nextLocation) { var currentIndex = getCurrentIndex(); currentLocation = nextLocation; if (currentLocation.action === _Actions.PUSH) { allKeys = [].concat(allKeys.slice(0, currentIndex + 1), [currentLocation.key]); } else if (currentLocation.action === _Actions.REPLACE) { allKeys[currentIndex] = currentLocation.key; } listeners.forEach(function (listener) { return listener(currentLocation); }); }; // beforeListeners回调队列中添加listener,返回函数用于移除beforeListeners中的listener var listenBefore = function listenBefore(listener) { beforeListeners.push(listener); return function () { return beforeListeners = beforeListeners.filter(function (item) { return item !== listener; }); }; }; // listeners回调队列中添加listener,返回函数用于移除listeners中的listener var listen = function listen(listener) { listeners.push(listener); return function () { return listeners = listeners.filter(function (item) { return item !== listener; }); }; }; // 迭代执行beforeListeners[index](location),完成后执行callback回调 var confirmTransitionTo = function confirmTransitionTo(location, callback) { // 使用迭代器方式同步执行beforeListeners中的函数,index为该函数在beforeListeners中的序号 // 迭代完成,执行callback回调 // transitionTo函数中调用confirmTransitionTo,callback回调的意义是更新页面location、存储location数据 (0, _AsyncUtils.loopAsync)(beforeListeners.length, function (index, next, done) { // 执行beforeListeners[index](location),返回值为null时通过next函数调用beforeListeners[index+1] // result为beforeListeners[index](location)的返回值 (0, _runTransitionHook2.default)(beforeListeners[index], location, function (result) { return result != null ? done(result) : next(); }); }, function (message) { if (getUserConfirmation && typeof message === 'string') { getUserConfirmation(message, function (ok) { return callback(ok !== false); }); } else { callback(message !== false); } }); }; // 迭代执行前置钩子beforeListeners,变更浏览器location及window.sessionStorage存储的过程 // 更新allKeys页面路径修改记录,执行listener后置钩子 // HashProtocol.startListener(history.transitionTo, pathCoder, queryKey)绑定为hashChange事件发生时调用 var transitionTo = function transitionTo(nextLocation) { // nextLocation哈希路径数据同当前的哈希路径数据currentLocation或待更新的哈希路径数据pendingLocation相同 // 跳过变更浏览器location及window.sessionStorage存储的过程 if (currentLocation && (0, _LocationUtils.locationsAreEqual)(currentLocation, nextLocation) || pendingLocation && (0, _LocationUtils.locationsAreEqual)(pendingLocation, nextLocation)) return; pendingLocation = nextLocation; confirmTransitionTo(nextLocation, function (ok) { if (pendingLocation !== nextLocation) return; // Transition was interrupted during confirmation pendingLocation = null; if (ok) { // 待变更的location数据nextLocation和当前location数据currentLocation相同 // nextLocation.action赋值为_Actions.REPLACE if (nextLocation.action === _Actions.PUSH) { var prevPath = (0, _PathUtils.createPath)(currentLocation); var nextPath = (0, _PathUtils.createPath)(nextLocation); if (nextPath === prevPath && (0, _LocationUtils.statesAreEqual)(currentLocation.state, nextLocation.state)) nextLocation.action = _Actions.REPLACE; } // nextLocation.action为_Actions.POP时,只触发listeners回调函数队列执行 if (nextLocation.action === _Actions.POP) { updateLocation(nextLocation); // nextLocation.action为_Actions.PUSH时,allKeys添加nextLocation.key // 更新window.location页面路径,window.sessionStorage存储{[key]:state} // pushLocation(nextLocation)不返回false时(默认undefined),触发listeners回调 } else if (nextLocation.action === _Actions.PUSH) { if (pushLocation(nextLocation) !== false) updateLocation(nextLocation); // nextLocation.action为_Actions.PUSH时,allKeys替换currentLocation.key为nextLocation.key // 更新window.location页面路径,window.sessionStorage存储{[key]:state} // pushLocation(nextLocation)不返回false时(默认undefined),触发listeners回调 } else if (nextLocation.action === _Actions.REPLACE) { if (replaceLocation(nextLocation) !== false) updateLocation(nextLocation); } // 最末一个beforeListeners返回undefined或false时,使用go函数进行页面跳转 } else if (currentLocation && nextLocation.action === _Actions.POP) { var prevIndex = allKeys.indexOf(currentLocation.key); var nextIndex = allKeys.indexOf(nextLocation.key); if (prevIndex !== -1 && nextIndex !== -1) go(prevIndex - nextIndex); } }); }; // 迭代执行前置钩子beforeListeners,变更浏览器location及window.sessionStorage存储的过程 // 更新allKeys添加一条页面路径修改记录,执行listener后置钩子 var push = function push(input) { return transitionTo(createLocation(input, _Actions.PUSH)); }; // 迭代执行前置钩子beforeListeners,变更浏览器location及window.sessionStorage存储的过程 // 更新allKeys替换一条页面路径修改记录,执行listener后置钩子 var replace = function replace(input) { return transitionTo(createLocation(input, _Actions.REPLACE)); }; // 内部调用window.history.go处理传参 var goBack = function goBack() { return go(-1); }; var goForward = function goForward() { return go(1); }; // 随机生成一个key,作为查询字符串中的值,以及window.sessionStorage中的键 var createKey = function createKey() { return Math.random().toString(36).substr(2, keyLength || 6); }; // 生成路径 var createHref = function createHref(location) { return (0, _PathUtils.createPath)(location); }; // createLocation(obj={pathname,search,hash,state}|path,action=undefined,key) // 将location数据转化为对象形式输出{pathname,search,hash,state,action,key} var createLocation = function createLocation(location, action) { var key = arguments.length <= 2 || arguments[2] === undefined ? createKey() : arguments[2]; return (0, _LocationUtils.createLocation)(location, action, key); }; return { getCurrentLocation: getCurrentLocation,// 获取当前location数据{pathname,search,hash,state,action,key} listenBefore: listenBefore,// 添加前置钩子 listen: listen,// 添加后置钩子 transitionTo: transitionTo,// 变更页面路径、更新window.sessionStorage、执行钩子函数,更新allKeys,可作为页面路径变更时的回调 push: push,// transitionTo方法变更页面路径、更新window.sessionStorage、执行钩子函数,allKeys添加一条路径记录,可作为页面路径变更时的回调 replace: replace,// transitionTo方法变更页面路径、更新window.sessionStorage、执行钩子函数,allKeys替换一条路径记录,可作为页面路径变更时的回调 go: go,// window.history.go跳转页面 goBack: goBack,// window.history.go跳转页面 goForward: goForward,// window.history.go跳转页面 createKey: createKey,// 随机生成一个key,作为查询字符串中的值,以及window.sessionStorage中的键 createPath: _PathUtils.createPath,// 生成路径 createHref: createHref,// 生成路径 createLocation: createLocation// 生成location数据 }; }; exports.default = createHistory;
HashProtocol.js获取当前的哈希路径数据、更新哈希路径数据(也改变location的哈希值)、绑定函数监听hashchange事件
createHashHistory.js创建hashHistory对象,内含变更页面路径到更新location数据到执行绑点函数的一般方法
/*---------- HashProtocol.js模块 -----------*/ 'use strict'; exports.__esModule = true; exports.replaceLocation = exports.pushLocation = exports.startListener = exports.getCurrentLocation = exports.go = exports.getUserConfirmation = undefined; var _BrowserProtocol = require('./BrowserProtocol'); // HashProtocol.getUserConfirmation(message,callback) 在callback回调中定制执行window.confirm(message) Object.defineProperty(exports, 'getUserConfirmation', { enumerable: true, get: function get() { return _BrowserProtocol.getUserConfirmation; } }); // 内部调用window.history.go处理传参 Object.defineProperty(exports, 'go', { enumerable: true, get: function get() { return _BrowserProtocol.go; } }); // node模块;warning(condition,format,args) 开发环境下,condition为否值时,使用args替换报错字符串模板format输出 // _warning2.default引用_warning,即node模块warning var _warning = require('warning'); var _warning2 = _interopRequireDefault(_warning); // 创建、比较location数据对象方法集 var _LocationUtils = require('./LocationUtils'); // 封装浏览器绑定、移除函数方法,以及路径相关方法能力检测 var _DOMUtils = require('./DOMUtils'); // 使用window.sessionStorage(当前页面有效)存储及读取location.state数据 var _DOMStateStorage = require('./DOMStateStorage'); // 路径操作工具函数集 var _PathUtils = require('./PathUtils'); // obj为history模块内建模块(函数),原样输出;否则将函数挂载在default方法上 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HashChangeEvent = 'hashchange'; // 获取window.location.href下“#”后的内容,作为哈希路径hashPath var getHashPath = function getHashPath() { var href = window.location.href; var hashIndex = href.indexOf('#'); return hashIndex === -1 ? '' : href.substring(hashIndex + 1); }; // 通过windows.location.hash=path重新赋值哈希路径 var pushHashPath = function pushHashPath(path) { return window.location.hash = path; }; // 通过拼接window.location.href重新赋值哈希路径 var replaceHashPath = function replaceHashPath(path) { var hashIndex = window.location.href.indexOf('#'); window.location.replace(window.location.href.slice(0, hashIndex >= 0 ? hashIndex : 0) + '#' + path); }; // 通过window.location.href、window.sessionStorage获取location哈希路径数据{pathname,search,hash,state,action,key} // queryKey是hashPath中查询字符串的键,用于获取window.sessionStorage存储location.state数据的key值 var getCurrentLocation = exports.getCurrentLocation = function getCurrentLocation(pathCoder, queryKey) { // 获取哈希路径hashPath var path = pathCoder.decodePath(getHashPath()); // _PathUtils.getQueryStringValueFromPath获取哈希路径hashPath下查询字符串search中,queryKey键的值 var key = (0, _PathUtils.getQueryStringValueFromPath)(path, queryKey); var state = void 0; if (key) { // hashPath下下查询字符串中含有key键值,替换为"?"或"#",重新拼接路径输出 path = (0, _PathUtils.stripQueryStringValueFromPath)(path, queryKey); // 读取window.sessionStorage(当前页面有效)存储的location.state数据 state = (0, _DOMStateStorage.readState)(key); } var init = (0, _PathUtils.parsePath)(path); init.state = state; // _LocationUtils.createLocation(obj={pathname,search,hash,state},action=undefined,key) // 将location数据转化为对象形式输出{pathname,search,hash,state,action,key} return (0, _LocationUtils.createLocation)(init, undefined, key); }; var prevLocation = void 0;// 闭包缓存之前存储的location哈希路径数据 // 绑定函数listener(以哈希路径数据{pathname,search,hash,state,action,key}为参数),监听hashChange事件 var startListener = exports.startListener = function startListener(listener, pathCoder, queryKey) { var handleHashChange = function handleHashChange() { var path = getHashPath(); var encodedPath = pathCoder.encodePath(path); if (path !== encodedPath) { // 确保哈希录路径按pathCoder定义格式书写,否则重写哈希路径(同时将触发hashChange事件,所有浏览器兼容) replaceHashPath(encodedPath); } else { var currentLocation = getCurrentLocation(pathCoder, queryKey); if (prevLocation && currentLocation.key && prevLocation.key === currentLocation.key) return; prevLocation = currentLocation; // 执行listener回调函数,以哈希路径数据{pathname,search,hash,state,action,key}为参数 listener(currentLocation); } }; // 确保哈希录路径按pathCoder定义格式书写,否则重写哈希路径(同时将触发hashChange事件,所有浏览器兼容) var path = getHashPath(); var encodedPath = pathCoder.encodePath(path); if (path !== encodedPath) replaceHashPath(encodedPath); // 绑定函数,监听hashChange事件 (0, _DOMUtils.addEventListener)(window, HashChangeEvent, handleHashChange); // 返回移除函数 return function () { return (0, _DOMUtils.removeEventListener)(window, HashChangeEvent, handleHashChange); }; }; // 由哈希路径数据location、哈希路径书写约定pathCoder、哈希路径下查询字符串的键queryKey,重新获取哈希路径 // 哈希路径hashPath已变更,则使用windows.location.hash=path重新赋值当前hash路径,不刷新页面 var updateLocation = function updateLocation(location, pathCoder, queryKey, updateHash) { var state = location.state; var key = location.key; // 由location拼接生成路径,实质是哈希路径hashPath内容,hash路径部分符合pathCoder约定的书写格式 var path = pathCoder.encodePath((0, _PathUtils.createPath)(location)); if (state !== undefined) { // hashPath下路径下添加queryKey+"="+key形式的查询字符串 path = (0, _PathUtils.addQueryStringValueToPath)(path, queryKey, key); // window.sessionStorage存储{[key]:state}形式的location哈希路径数据 (0, _DOMStateStorage.saveState)(key, state); } prevLocation = location; // 哈希路径hashPath已变更,则使用windows.location.hash=path重新赋值当前hash路径,不刷新页面 updateHash(path); }; // 哈希路径重新赋值,并使用window.sessionStorage存储{[key]:state}形式的location哈希路径数据 var pushLocation = exports.pushLocation = function pushLocation(location, pathCoder, queryKey) { return updateLocation(location, pathCoder, queryKey, function (path) { // 哈希路径hashPath已变更,则使用windows.location.hash=path重新赋值当前hash路径,不刷新页面 // 哈希路径未变更,开发环境下警告提示 if (getHashPath() !== path) { pushHashPath(path); } else { process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(false, 'You cannot PUSH the same path using hash history') : void 0; } }); }; // 替换哈希路径,并使用window.sessionStorage存储{[key]:state}形式的location哈希路径数据 var replaceLocation = exports.replaceLocation = function replaceLocation(location, pathCoder, queryKey) { return updateLocation(location, pathCoder, queryKey, function (path) { if (getHashPath() !== path) replaceHashPath(path); }); }; /*---------- createHashHistory.js模块 -----------*/ 'use strict'; exports.__esModule = true; // 类似jquery.extend,将带靠背对象浅拷贝给目标对象 var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // node模块;warning(condition,format,args) 开发环境下,condition为否值时,使用args替换报错字符串模板format输出 // _warning2.default引用_warning,即node模块warning var _warning = require('warning'); var _warning2 = _interopRequireDefault(_warning); // node模块;invariant(condition,format,a,b,c,d,e,f),condition为否值时,以a,b,c,d,e,f替换报错模板字符串format,抛出错误 // _invariant2.default引用_invariant,即node模块invariant var _invariant = require('invariant'); var _invariant2 = _interopRequireDefault(_invariant); // 判断平台是否为浏览器环境,可以操作dom节点 var _ExecutionEnvironment = require('./ExecutionEnvironment'); // 封装浏览器绑定、移除函数方法,以及路径相关方法能力检测 var _DOMUtils = require('./DOMUtils'); // 哈希路径数据操作方法集,包括获取当前的哈希路径数据、更新哈希路径数据(也改变location的哈希值)、绑定函数监听hashchange事件 var _HashProtocol = require('./HashProtocol'); var HashProtocol = _interopRequireWildcard(_HashProtocol); // 创建histroy方法,内含变更页面路径到更新location数据到执行绑点函数的一般方法,createHashHistory将重写个中方法 var _createHistory = require('./createHistory'); var _createHistory2 = _interopRequireDefault(_createHistory); // obj为history模块内建模块(对象),原样输出;否则转化为纯对象输出 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } // obj为history模块内建模块(函数),原样输出;否则将函数挂载在default方法上 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var DefaultQueryKey = '_k'; var addLeadingSlash = function addLeadingSlash(path) { return path.charAt(0) === '/' ? path : '/' + path; }; // 定义hash路径书写格式,hashbang以"!"起始,noslash直接跟路径,slash以"/"起始 var HashPathCoders = { hashbang: { encodePath: function encodePath(path) { return path.charAt(0) === '!' ? path : '!' + path; }, decodePath: function decodePath(path) { return path.charAt(0) === '!' ? path.substring(1) : path; } }, noslash: { encodePath: function encodePath(path) { return path.charAt(0) === '/' ? path.substring(1) : path; }, decodePath: addLeadingSlash }, // 以"/"作为window.location.href下“#”后哈希路径hashPath的起始符 slash: { encodePath: addLeadingSlash, decodePath: addLeadingSlash } }; // createHashHistory(options),创建hashHistory对象,内含变更页面路径到更新location数据到执行绑点函数的一般方法 // options.queryKey 不能设置为false,哈希路径中查询字符串的键,值为window.sessionStorage存储state的键 // options.hashType 须是hashbang、noslash、slash中的一个,默认slash,规定哈希路径hashPath类型 // hashbang以"!"起始,noslash直接跟路径,slash以"/"起始 // 返回值 // { // getUserConfirmation,// getUserConfirmation(message,callback) 在callback回调中定制执行window.confirm(message) // queryKey,// 哈希路径中查询字符串的键,值为window.sessionStorage存储state的键 // hashType,// 规定哈希路径hashPath书写形式 // getCurrentLocation,// 获取当前location数据{pathname,search,hash,state,action,key} // pushLocation,// 哈希路径重新赋值,并使用window.sessionStorage存储{[key]:state}形式的location哈希路径数据 // replaceLocation,// 哈希路径重新赋值,并使用window.sessionStorage存储{[key]:state}形式的location哈希路径数据 // listenBefore,// 将transitionTo方法绑定到hashChange事件上,添加前置钩子;事件触发时,执行钩子,及变更浏览器location及window.sessionStorage存储 // listen,// 将transitionTo方法绑定到hashChange事件上,添加后置钩子;事件触发时,执行钩子,及变更浏览器location及window.sessionStorage存储 // transitionTo,// 变更页面路径、更新window.sessionStorage、执行钩子函数,更新allKeys,可作为页面路径变更时的回调 // push,// transitionTo方法变更页面路径、更新window.sessionStorage、执行钩子函数,allKeys添加一条路径记录,可作为页面路径变更时的回调 // replace,// transitionTo方法变更页面路径、更新window.sessionStorage、执行钩子函数,allKeys替换一条路径记录,可作为页面路径变更时的回调 // go,// window.history.go跳转页面 // goBack,// window.history.go跳转页面 // goForward,// window.history.go跳转页面 // createKey,// 随机生成一个key,作为查询字符串中的值,以及window.sessionStorage中的键 // createPath,// 生成路径 // createHref,// 生成哈希路径 // createLocation,// 生成location数据 // } var createHashHistory = function createHashHistory() { // 首参有效 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; // 不是浏览器环境报错 !_ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? (0, _invariant2.default)(false, 'Hash history needs a DOM') : (0, _invariant2.default)(false) : void 0; var queryKey = options.queryKey; var hashType = options.hashType; // options.queryKey设置为false,报错 process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(queryKey !== false, 'Using { queryKey: false } no longer works. Instead, just don\'t ' + 'use location state if you don\'t want a key in your URL query string') : void 0; if (typeof queryKey !== 'string') queryKey = DefaultQueryKey; if (hashType == null) hashType = 'slash'; // options.hashType不是hashbang、noslash、slash中的一个,报错 if (!(hashType in HashPathCoders)) { process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(false, 'Invalid hash type: %s', hashType) : void 0; hashType = 'slash'; } var pathCoder = HashPathCoders[hashType]; // HashProtocol.getUserConfirmation(message,callback) 在callback回调中定制执行window.confirm(message) var getUserConfirmation = HashProtocol.getUserConfirmation; // 通过window.location.href、window.sessionStorage获取location数据{pathname,search,hash,state,action,key} var getCurrentLocation = function getCurrentLocation() { return HashProtocol.getCurrentLocation(pathCoder, queryKey); }; // 哈希路径重新赋值,并使用window.sessionStorage存储{[key]:state}形式的location哈希路径数据 var pushLocation = function pushLocation(location) { return HashProtocol.pushLocation(location, pathCoder, queryKey); }; // 替换哈希路径,并使用window.sessionStorage存储{[key]:state}形式的location哈希路径数据 var replaceLocation = function replaceLocation(location) { return HashProtocol.replaceLocation(location, pathCoder, queryKey); }; var history = (0, _createHistory2.default)(_extends({ getUserConfirmation: getUserConfirmation }, options, { getCurrentLocation: getCurrentLocation, pushLocation: pushLocation, replaceLocation: replaceLocation, go: HashProtocol.go// 内部调用window.history.go处理传参 })); var listenerCount = 0,// 用以限制history.transitionTo函数绑定到hashChange事件上只一次 stopListener = void 0; // 将history.transitionTo函数绑定到hashChange事件上 // hashChange事件触发时,执行钩子函数,及变更浏览器location及window.sessionStorage存储 var startListener = function startListener(listener, before) { if (++listenerCount === 1){ // 将history.transitionTo函数绑定到hashChange事件上 // 迭代执行前置钩子beforeListeners,变更浏览器location及window.sessionStorage存储的过程 // 更新allKeys页面路径修改记录,执行listener后置钩子 stopListener = HashProtocol.startListener(history.transitionTo, pathCoder, queryKey); } // 添加前置钩子或后置钩子 var unlisten = before ? history.listenBefore(listener) : history.listen(listener); // 移除绑定hashChange事件上的history.transitionTo函数及listener钩子函数 return function () { unlisten(); if (--listenerCount === 0) stopListener(); }; }; // 将history.transitionTo函数绑定到hashChange事件上,并添加前置钩子 // hashChange事件触发时,执行钩子函数,及变更浏览器location及window.sessionStorage存储 var listenBefore = function listenBefore(listener) { return startListener(listener, true); }; // 将history.transitionTo函数绑定到hashChange事件上,并添加后置钩子 // hashChange事件触发时,执行钩子函数,及变更浏览器location及window.sessionStorage存储 var listen = function listen(listener) { return startListener(listener, false); }; // 能力检测,判断window.history.go(n)方法更新哈希路径是否会导致页面重新加载 var goIsSupportedWithoutReload = (0, _DOMUtils.supportsGoWithoutReloadUsingHash)(); // 内部调用window.history.go处理传参 var go = function go(n) { // window.history.go(n)方法更新哈希路径将导致页面重新加载,报错 process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(goIsSupportedWithoutReload, 'Hash history go(n) causes a full page reload in this browser') : void 0; history.go(n); }; // 生成哈希路径 var createHref = function createHref(path) { return '#' + pathCoder.encodePath(history.createHref(path)); }; return _extends({}, history, { listenBefore: listenBefore, listen: listen, go: go, createHref: createHref }); }; exports.default = createHashHistory;
BrowserProtocol.js获取当前的路径数据、创建路径数据、更新路径数据(也改变页面的location)、绑定函数监听popState或hashchange事件
RefreshProtocol.js.js获取当前的路径数据、更新路径数据(也改变页面的location)
createBrowserHistory.js创建hashHistory对象,内含变更页面路径到更新location数据到执行绑点函数的一般方法
/*---------- BrowserProtocol.js模块 -----------*/ 'use strict'; exports.__esModule = true; exports.go = exports.replaceLocation = exports.pushLocation = exports.startListener = exports.getUserConfirmation = exports.getCurrentLocation = undefined; // 创建、比较location数据对象方法集 var _LocationUtils = require('./LocationUtils'); // 封装浏览器绑定、移除函数方法,以及路径相关方法能力检测 var _DOMUtils = require('./DOMUtils'); // 使用window.sessionStorage(当前页面有效)存储及读取location.state数据 var _DOMStateStorage = require('./DOMStateStorage'); // 路径操作工具函数集 var _PathUtils = require('./PathUtils'); // 判断平台是否为浏览器环境,可以操作dom节点 var _ExecutionEnvironment = require('./ExecutionEnvironment'); var PopStateEvent = 'popstate'; var HashChangeEvent = 'hashchange'; // _DOMUtils.supportsPopstateOnHashchange能力检测,判断哈希路径改变时是否会触发popstate事件 var needsHashchangeListener = _ExecutionEnvironment.canUseDOM && !(0, _DOMUtils.supportsPopstateOnHashchange)(); // 通过{state}生成location数据 var _createLocation = function _createLocation(historyState) { var key = historyState && historyState.key; return (0, _LocationUtils.createLocation)({ pathname: window.location.pathname, search: window.location.search, hash: window.location.hash, state: key ? (0, _DOMStateStorage.readState)(key) : undefined }, undefined, key); }; // 获取html5的window.history.state数据,用以生成生成location数据 var getCurrentLocation = exports.getCurrentLocation = function getCurrentLocation() { var historyState = void 0; try { historyState = window.history.state || {}; } catch (error) { // IE 11 sometimes throws when accessing window.history.state historyState = {}; } return _createLocation(historyState); }; // BrowserProtocol.getUserConfirmation(message,callback) 在callback回调中定制执行window.confirm(message) var getUserConfirmation = exports.getUserConfirmation = function getUserConfirmation(message, callback) { return callback(window.confirm(message)); }; // 在popstate、hashChange事件上绑定listener(location)回调 var startListener = exports.startListener = function startListener(listener) { var handlePopState = function handlePopState(event) { if (event.state !== undefined) // Ignore extraneous popstate events in WebKit listener(_createLocation(event.state)); }; // 绑定listener(location)回调,H5的popState事件在history.pushState|repleaceState方法调用时触发 (0, _DOMUtils.addEventListener)(window, PopStateEvent, handlePopState); var handleUnpoppedHashChange = function handleUnpoppedHashChange() { return listener(getCurrentLocation()); }; // 浏览器不支持popstate事件(重设哈希路径时触发),换用hashChange事件绑定listener(location)回调 if (needsHashchangeListener) { (0, _DOMUtils.addEventListener)(window, HashChangeEvent, handleUnpoppedHashChange); } // 事件解绑 return function () { (0, _DOMUtils.removeEventListener)(window, PopStateEvent, handlePopState); if (needsHashchangeListener) { (0, _DOMUtils.removeEventListener)(window, HashChangeEvent, handleUnpoppedHashChange); } }; }; // window.sessionStorage存储{[key]:state}形式的location路径数据 // pushLocation方法调用时,window.history.pushState({key},_PathUtils.createPath(location)) // replaceLocation方法调用时,window.history.replaceState({key},_PathUtils.createPath(location)) var updateLocation = function updateLocation(location, updateState) { var state = location.state; var key = location.key; if (state !== undefined) (0, _DOMStateStorage.saveState)(key, state); updateState({ key: key }, (0, _PathUtils.createPath)(location)); }; // window.sessionStorage存储{[key]:state}形式的location路径数据 // window.history.state存储{key:location.key},页面路径后加"/"+path var pushLocation = exports.pushLocation = function pushLocation(location) { return updateLocation(location, function (state, path) { return window.history.pushState(state, null, path); }); }; // window.sessionStorage存储{[key]:state}形式的location路径数据 // window.history.state存储{key:location.key},页面路径后加"/"+path var replaceLocation = exports.replaceLocation = function replaceLocation(location) { return updateLocation(location, function (state, path) { return window.history.replaceState(state, null, path); }); }; // 内部调用window.history.go处理传参 var go = exports.go = function go(n) { if (n) window.history.go(n); }; /*---------- RefreshProtocol.js模块 -----------*/ 'use strict'; exports.__esModule = true; exports.replaceLocation = exports.pushLocation = exports.getCurrentLocation = exports.go = exports.getUserConfirmation = undefined; var _BrowserProtocol = require('./BrowserProtocol'); // HashProtocol.getUserConfirmation(message,callback) 在callback回调中定制执行window.confirm(message) Object.defineProperty(exports, 'getUserConfirmation', { enumerable: true, get: function get() { return _BrowserProtocol.getUserConfirmation; } }); // 内部调用window.history.go处理传参 Object.defineProperty(exports, 'go', { enumerable: true, get: function get() { return _BrowserProtocol.go; } }); // 创建、比较location数据对象方法集 var _LocationUtils = require('./LocationUtils'); // 路径操作工具函数集 var _PathUtils = require('./PathUtils'); // 获取当前的路径数据{pathname,search,hash,state,action,key} var getCurrentLocation = exports.getCurrentLocation = function getCurrentLocation() { return (0, _LocationUtils.createLocation)(window.location); }; // 使用window.location.href=path变更页面路径 var pushLocation = exports.pushLocation = function pushLocation(location) { window.location.href = (0, _PathUtils.createPath)(location); return false; }; // 使用window.location.replace(path)变更页面路径 var replaceLocation = exports.replaceLocation = function replaceLocation(location) { window.location.replace((0, _PathUtils.createPath)(location)); return false; }; /*---------- createBrowserHistory.js模块 -----------*/ 'use strict'; exports.__esModule = true; // 类似jquery.extend,将带靠背对象浅拷贝给目标对象 var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // node模块;invariant(condition,format,a,b,c,d,e,f),condition为否值时,以a,b,c,d,e,f替换报错模板字符串format,抛出错误 // _invariant2.default引用_invariant,即node模块invariant var _invariant = require('invariant'); var _invariant2 = _interopRequireDefault(_invariant); // 判断平台是否为浏览器环境,可以操作dom节点 var _ExecutionEnvironment = require('./ExecutionEnvironment'); // 路径数据操作方法集,包括获取当前的路径数据、更新路径数据(也改变location的路径值)、绑定函数监听hashchange或popState事件 var _BrowserProtocol = require('./BrowserProtocol'); var BrowserProtocol = _interopRequireWildcard(_BrowserProtocol); // 路径数据操作方法集,包括获取当前的路径数据、改变页面路径location var _RefreshProtocol = require('./RefreshProtocol'); var RefreshProtocol = _interopRequireWildcard(_RefreshProtocol); // 封装浏览器绑定、移除函数方法,以及路径相关方法能力检测 var _DOMUtils = require('./DOMUtils'); // 创建histroy方法,内含变更页面路径到更新location数据到执行绑点函数的一般方法,createBrowserHistory将重写个中方法 var _createHistory = require('./createHistory'); var _createHistory2 = _interopRequireDefault(_createHistory); // obj为history模块内建模块(对象),原样输出;否则转化为纯对象输出 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } // obj为history模块内建模块(函数),原样输出;否则将函数挂载在default方法上 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // createBrowserHistory(options),构建browserHistory对象,内含变更页面路径到更新location数据到执行绑点函数的一般方法 // options.forceRefresh 强制使用window.location.href(path)或window.location.replace(path)更新页面路径 // 返回值 // { // getUserConfirmation,// getUserConfirmation(message,callback) 在callback回调中定制执行window.confirm(message) // forceRefresh,// 强制使用window.location.href(path)或window.location.replace(path)更新页面路径 // getCurrentLocation,// 获取当前location数据{pathname,search,hash,state,action,key} // pushLocation,// 路径重新赋值,并使用window.sessionStorage存储{[key]:state}形式的location路径数据 // replaceLocation,// 路径重新赋值,并使用window.sessionStorage存储{[key]:state}形式的location路径数据 // listenBefore,// 将transitionTo方法绑定到popState或hashChange事件上,添加前置钩子;事件触发时,执行钩子,及变更浏览器location及window.sessionStorage存储 // listen,// 将transitionTo方法绑定到popState或hashChange事件上,添加后置钩子;事件触发时,执行钩子,及变更浏览器location及window.sessionStorage存储 // transitionTo,// 变更页面路径、更新window.sessionStorage、执行钩子函数,更新allKeys,可作为页面路径变更时的回调 // push,// transitionTo方法变更页面路径、更新window.sessionStorage、执行钩子函数,allKeys添加一条路径记录,可作为页面路径变更时的回调 // replace,// transitionTo方法变更页面路径、更新window.sessionStorage、执行钩子函数,allKeys替换一条路径记录,可作为页面路径变更时的回调 // go,// window.history.go跳转页面 // goBack,// window.history.go跳转页面 // goForward,// window.history.go跳转页面 // createKey,// 随机生成一个key,作为查询字符串中的值,以及window.sessionStorage中的键 // createPath,// 生成路径 // createHref,// 生成路径 // createLocation,// 生成location数据 // } var createBrowserHistory = function createBrowserHistory() { // 首参有效 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; // 不是浏览器环境报错 !_ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? (0, _invariant2.default)(false, 'Hash history needs a DOM') : (0, _invariant2.default)(false) : void 0; // _DOMUtils.supportsHistory能力检测,判断浏览器是否支持HTML5 history API var useRefresh = options.forceRefresh || !(0, _DOMUtils.supportsHistory)(); // 不支持h5的histroy方法或者options.forceRefresh为真 // 使用window.location.href(path)或window.location.replace(path)更新页面路径 // 否则以BrowserProtocol中window.history.pushState、window.history.replaceState更新页面路径 var Protocol = useRefresh ? RefreshProtocol : BrowserProtocol; var getUserConfirmation = Protocol.getUserConfirmation; var getCurrentLocation = Protocol.getCurrentLocation; var pushLocation = Protocol.pushLocation; var replaceLocation = Protocol.replaceLocation; var go = Protocol.go; var history = (0, _createHistory2.default)(_extends({ getUserConfirmation: getUserConfirmation }, options, { getCurrentLocation: getCurrentLocation, pushLocation: pushLocation, replaceLocation: replaceLocation, go: go// 内部调用window.history.go处理传参 })); var listenerCount = 0, stopListener = void 0; // 将history.transitionTo函数绑定到popState或hashChange事件上 // popState或hashChange事件触发时,执行钩子函数,及变更浏览器location及window.sessionStorage存储 var startListener = function startListener(listener, before) { // 将history.transitionTo函数绑定到popState或hashChange事件上 // 迭代执行前置钩子beforeListeners,变更浏览器location及window.sessionStorage存储的过程 // 更新allKeys页面路径修改记录,执行listener后置钩子 if (++listenerCount === 1) stopListener = BrowserProtocol.startListener(history.transitionTo); // 添加前置钩子或后置钩子 var unlisten = before ? history.listenBefore(listener) : history.listen(listener); // 移除绑定hashChange事件上的history.transitionTo函数及listener钩子函数 return function () { unlisten(); if (--listenerCount === 0) stopListener(); }; }; // 将history.transitionTo函数绑定到popState或hashChange事件上,并添加前置钩子 // popState或hashChange事件触发时,执行钩子函数,及变更浏览器location及window.sessionStorage存储 var listenBefore = function listenBefore(listener) { return startListener(listener, true); }; // 将history.transitionTo函数绑定到popState或hashChange事件上,并添加后置钩子 // popState或hashChange事件触发时,执行钩子函数,及变更浏览器location及window.sessionStorage存储 var listen = function listen(listener) { return startListener(listener, false); }; return _extends({}, history, { listenBefore: listenBefore, listen: listen }); }; exports.default = createBrowserHistory;
createMemoryHistory.js使用js闭包缓存特点构建{key:state}存储机制,存储在闭包变量storage中
'use strict'; exports.__esModule = true; // 类似jquery.extend,将带靠背对象浅拷贝给目标对象 var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // node模块;warning(condition,format,args) 开发环境下,condition为否值时,使用args替换报错字符串模板format输出 // _warning2.default引用_warning,即node模块warning var _warning = require('warning'); var _warning2 = _interopRequireDefault(_warning); // node模块;invariant(condition,format,a,b,c,d,e,f),condition为否值时,以a,b,c,d,e,f替换报错模板字符串format,抛出错误 // _invariant2.default引用_invariant,即node模块invariant var _invariant = require('invariant'); var _invariant2 = _interopRequireDefault(_invariant); // 创建、比较location数据对象方法集 var _LocationUtils = require('./LocationUtils'); // 路径操作工具函数集 var _PathUtils = require('./PathUtils'); // 创建histroy方法,内含变更页面路径到更新location数据到执行绑点函数的一般方法,createHashHistory将重写个中方法 var _createHistory = require('./createHistory'); var _createHistory2 = _interopRequireDefault(_createHistory); // location.action允许的值 var _Actions = require('./Actions'); // obj为history模块内建模块(函数),原样输出;否则将函数挂载在default方法上 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // 将[{key:state}]转化为对象形式{key:state} var createStateStorage = function createStateStorage(entries) { return entries.filter(function (entry) { return entry.state; }).reduce(function (memo, entry) { memo[entry.key] = entry.state; return memo; }, {}); }; // options.entries options为路径对象{path,search,hash,key,state}构成的数组时,将options赋值给options.entries; // options为字符串时,将[options]赋值给options.entries // options.current 默认取options.entries.length-1 // 返回值 // { // entries,// {path,search,hash,key,state}对象构成的路径数据数组 // getCurrentLocation,// 获取当前location数据{pathname,search,hash,state,action,key} // pushLocation,// entries、storage添加一条路径记录 // replaceLocation,// entries、storage替换一条路径记录 // listenBefore,// 添加后置钩子 // listen,// 添加后置钩子 // transitionTo,// 变更页面路径、更新storage、执行钩子函数,更新allKeys,可作为页面路径变更时的回调 // push,// transitionTo方法变更页面路径、更新storage、执行钩子函数,allKeys添加一条路径记录,可作为页面路径变更时的回调 // replace,// transitionTo方法变更页面路径、更新storage、执行钩子函数,allKeys替换一条路径记录,可作为页面路径变更时的回调 // go,// 变更页面路径、更新storage、执行钩子函数,更新allKeys // goBack,// window.history.go跳转页面 // goForward,// window.history.go跳转页面 // createKey,// 随机生成一个key,作为查询字符串中的值,以及window.sessionStorage中的键 // createPath,// 生成路径 // createHref,// 生成哈希路径 // createLocation,// 生成location数据 // } var createMemoryHistory = function createMemoryHistory() { // 首参有效 var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; if (Array.isArray(options)) { options = { entries: options }; } else if (typeof options === 'string') { options = { entries: [options] }; } // 通过options.current获取location数据{pathname,search,hash,state,action,key} var getCurrentLocation = function getCurrentLocation() { var entry = entries[current];// options.current var path = (0, _PathUtils.createPath)(entry); var key = void 0, state = void 0; if (entry.key) { key = entry.key; state = readState(key); } var init = (0, _PathUtils.parsePath)(path); return (0, _LocationUtils.createLocation)(_extends({}, init, { state: state }), undefined, key); }; // 是否支持跳转到entries[current+n]路径对象下 var canGo = function canGo(n) { var index = current + n; return index >= 0 && index < entries.length; }; // 迭代执行前置钩子beforeListeners,变更浏览器location及storage存储的过程 // 更新allKeys页面路径修改记录,执行listener后置钩子 var go = function go(n) { if (!n) return; if (!canGo(n)) { process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(false, 'Cannot go(%s) there is not enough history', n) : void 0; return; } current += n; var currentLocation = getCurrentLocation(); history.transitionTo(_extends({}, currentLocation, { action: _Actions.POP })); }; // entries、storage添加一条路径记录 var pushLocation = function pushLocation(location) { current += 1; if (current < entries.length) entries.splice(current); entries.push(location); saveState(location.key, location.state); }; // entries、storage替换一条路径记录 var replaceLocation = function replaceLocation(location) { entries[current] = location; saveState(location.key, location.state); }; var history = (0, _createHistory2.default)(_extends({}, options, { getCurrentLocation: getCurrentLocation, pushLocation: pushLocation, replaceLocation: replaceLocation, go: go })); var _options = options; var entries = _options.entries;// 闭包缓存,[{key:state}]数组形式 var current = _options.current;// 闭包缓存 if (typeof entries === 'string') { entries = [entries]; } else if (!Array.isArray(entries)) { entries = ['/']; } // 将options.entries中的字符串内容解析为{key}对象形式 entries = entries.map(function (entry) { return (0, _LocationUtils.createLocation)(entry); }); // current默认赋值为options.entries.length-1;不在options.entries长度范围内,报错 if (current == null) { current = entries.length - 1; } else { !(current >= 0 && current < entries.length) ? process.env.NODE_ENV !== 'production' ? (0, _invariant2.default)(false, 'Current index must be >= 0 and < %s, was %s', entries.length, current) : (0, _invariant2.default)(false) : void 0; } // 将options.entries的值[{key:state}]转化为对象形式{key:state}输出,闭包缓存,{key:state}对象形式 var storage = createStateStorage(entries); // 更新storage[key]存储的state数据 var saveState = function saveState(key, state) { return storage[key] = state; }; // 获取storage[key]存储的state数据 var readState = function readState(key) { return storage[key]; }; return _extends({}, history, { canGo: canGo }); }; // 使用js闭包缓存特点构建{key:state}存储机制 exports.default = createMemoryHistory;
useBasename.js通过装饰createBrowserHistory、createHashHistory、createMemoryHistory,达到操作location数据对象时分离basename的目的
'use strict'; exports.__esModule = true; // 类似jquery.extend,将带靠背对象浅拷贝给目标对象 var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // runTransitionHook(hook,location,callback) // 执行hook(location),callback为hook函数执行完成后的回调 // 执行hook(location,callback),callback在hook函数内部调用,hook不能返回真值 var _runTransitionHook = require('./runTransitionHook'); var _runTransitionHook2 = _interopRequireDefault(_runTransitionHook); // 路径操作工具函数集 var _PathUtils = require('./PathUtils'); // obj为history模块内建模块(函数),原样输出;否则将函数挂载在default方法上 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var useBasename = function useBasename(createHistory) { // 装饰createHistory函数,操作location数据对象时分离basename,返回装饰函数 return function () { var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; var history = createHistory(options); var basename = options.basename; // location路径数据对象添加basename属性,pathname根据basename进行调整 var addBasename = function addBasename(location) { if (!location) return location; if (basename && location.basename == null) { if (location.pathname.indexOf(basename) === 0) { location.pathname = location.pathname.substring(basename.length); location.basename = basename; if (location.pathname === '') location.pathname = '/'; } else { location.basename = ''; } } return location; }; // 操作pathname的时候,将basename前插到pathname字符串前 var prependBasename = function prependBasename(location) { if (!basename) return location; var object = typeof location === 'string' ? (0, _PathUtils.parsePath)(location) : location; var pname = object.pathname; var normalizedBasename = basename.slice(-1) === '/' ? basename : basename + '/'; var normalizedPathname = pname.charAt(0) === '/' ? pname.slice(1) : pname; var pathname = normalizedBasename + normalizedPathname; return _extends({}, object, { pathname: pathname }); }; // 读取location数据对象时,分离basename作为单一的属性 var getCurrentLocation = function getCurrentLocation() { return addBasename(history.getCurrentLocation()); }; var listenBefore = function listenBefore(hook) { return history.listenBefore(function (location, callback) { return (0, _runTransitionHook2.default)(hook, addBasename(location), callback); }); }; var listen = function listen(listener) { return history.listen(function (location) { return listener(addBasename(location)); }); }; // 操作pathname时,将basename前插到pathname字符串前 var push = function push(location) { return history.push(prependBasename(location)); }; var replace = function replace(location) { return history.replace(prependBasename(location)); }; var createPath = function createPath(location) { return history.createPath(prependBasename(location)); }; var createHref = function createHref(location) { return history.createHref(prependBasename(location)); }; var createLocation = function createLocation(location) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } return addBasename(history.createLocation.apply(history, [prependBasename(location)].concat(args))); }; return _extends({}, history, { getCurrentLocation: getCurrentLocation, listenBefore: listenBefore, listen: listen, push: push, replace: replace, createPath: createPath, createHref: createHref, createLocation: createLocation }); }; }; // 装饰createHistory函数,操作location数据对象时分离basename,返回装饰函数 exports.default = useBasename;
useBeforeUnload.js通过装饰createBrowserHistory、createHashHistory、createMemoryHistory,添加listenBeforeUnload方法,达到监听'beforeunload'弹出警告的目的
'use strict'; exports.__esModule = true; // 类似jquery.extend,将带靠背对象浅拷贝给目标对象 var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // node模块;invariant(condition,format,a,b,c,d,e,f),condition为否值时,以a,b,c,d,e,f替换报错模板字符串format,抛出错误 // _invariant2.default引用_invariant,即node模块invariant var _invariant = require('invariant'); var _invariant2 = _interopRequireDefault(_invariant); // 封装浏览器绑定、移除函数方法,以及路径相关方法能力检测 var _DOMUtils = require('./DOMUtils'); // 判断平台是否为浏览器环境,可以操作dom节点 var _ExecutionEnvironment = require('./ExecutionEnvironment'); // obj为history模块内建模块(函数),原样输出;否则将函数挂载在default方法上 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var startListener = function startListener(getPromptMessage) { var handleBeforeUnload = function handleBeforeUnload(event) { var message = getPromptMessage(); if (typeof message === 'string') { (event || window.event).returnValue = message; return message; } return undefined; }; (0, _DOMUtils.addEventListener)(window, 'beforeunload', handleBeforeUnload); return function () { return (0, _DOMUtils.removeEventListener)(window, 'beforeunload', handleBeforeUnload); }; }; var useBeforeUnload = function useBeforeUnload(createHistory) { !_ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? (0, _invariant2.default)(false, 'useBeforeUnload only works in DOM environments') : (0, _invariant2.default)(false) : void 0; return function (options) { var history = createHistory(options); var listeners = []; var stopListener = void 0; var getPromptMessage = function getPromptMessage() { var message = void 0; for (var i = 0, len = listeners.length; message == null && i < len; ++i) { message = listeners[i].call(); }return message; }; // 关闭页面时执行listener,触发'beforeunload',listener返回值作为弹出警告,返回移除监听事件函数 var listenBeforeUnload = function listenBeforeUnload(listener) { if (listeners.push(listener) === 1) stopListener = startListener(getPromptMessage); return function () { listeners = listeners.filter(function (item) { return item !== listener; }); if (listeners.length === 0 && stopListener) { stopListener(); stopListener = null; } }; }; return _extends({}, history, { listenBeforeUnload: listenBeforeUnload }); }; }; // 装饰createHistory,添加listenBeforeUnload方法,返回值接受options作为参数,供createHistory(options)调用 // listenBeforeUnload方法,关闭页面时执行listener,触发'beforeunload',listener返回值作为弹出警告,返回移除监听事件函数 exports.default = useBeforeUnload;
useQueries.js通过装饰createBrowserHistory、createHashHistory、createMemoryHistory,达到操作location数据对象时分离location.query(对象化的查询字符串)的目的
'use strict'; exports.__esModule = true; // 类似jquery.extend,将带靠背对象浅拷贝给目标对象 var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // 解析查询字符串 var _queryString = require('query-string'); // runTransitionHook(hook,location,callback) // 执行hook(location),callback为hook函数执行完成后的回调 // 执行hook(location,callback),callback在hook函数内部调用,hook不能返回真值 var _runTransitionHook = require('./runTransitionHook'); var _runTransitionHook2 = _interopRequireDefault(_runTransitionHook); // 创建、比较location数据对象方法集 var _LocationUtils = require('./LocationUtils'); // 路径操作工具函数集 var _PathUtils = require('./PathUtils'); // obj为history模块内建模块(函数),原样输出;否则将函数挂载在default方法上 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var defaultStringifyQuery = function defaultStringifyQuery(query) { return (0, _queryString.stringify)(query).replace(/%20/g, '+'); }; var defaultParseQueryString = _queryString.parse; var useQueries = function useQueries(createHistory) { return function () { var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; var history = createHistory(options); var stringifyQuery = options.stringifyQuery; var parseQueryString = options.parseQueryString; if (typeof stringifyQuery !== 'function') stringifyQuery = defaultStringifyQuery; if (typeof parseQueryString !== 'function') parseQueryString = defaultParseQueryString; // 序列化查询字符串location.search,获取location.query var decodeQuery = function decodeQuery(location) { if (!location) return location; if (location.query == null) location.query = parseQueryString(location.search.substring(1)); return location; }; // 反序列化查询字符串location.query,获取location.search var encodeQuery = function encodeQuery(location, query) { if (query == null) return location; var object = typeof location === 'string' ? (0, _PathUtils.parsePath)(location) : location; var queryString = stringifyQuery(query); var search = queryString ? '?' + queryString : ''; return _extends({}, object, { search: search }); }; // 读取search的时候,对location.search进行序列化操作,获取location.query var getCurrentLocation = function getCurrentLocation() { return decodeQuery(history.getCurrentLocation()); }; var listenBefore = function listenBefore(hook) { return history.listenBefore(function (location, callback) { return (0, _runTransitionHook2.default)(hook, decodeQuery(location), callback); }); }; var listen = function listen(listener) { return history.listen(function (location) { return listener(decodeQuery(location)); }); }; // 操作search的时候,对location.query进行反序列化操作获取location.search var push = function push(location) { return history.push(encodeQuery(location, location.query)); }; var replace = function replace(location) { return history.replace(encodeQuery(location, location.query)); }; var createPath = function createPath(location) { return history.createPath(encodeQuery(location, location.query)); }; var createHref = function createHref(location) { return history.createHref(encodeQuery(location, location.query)); }; var createLocation = function createLocation(location) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } var newLocation = history.createLocation.apply(history, [encodeQuery(location, location.query)].concat(args)); if (location.query) newLocation.query = (0, _LocationUtils.createQuery)(location.query); return decodeQuery(newLocation); }; return _extends({}, history, { getCurrentLocation: getCurrentLocation, listenBefore: listenBefore, listen: listen, push: push, replace: replace, createPath: createPath, createHref: createHref, createLocation: createLocation }); }; }; exports.default = useQueries;
index.js对外接口
'use strict'; exports.__esModule = true; exports.locationsAreEqual = exports.Actions = exports.useQueries = exports.useBeforeUnload = exports.useBasename = exports.createMemoryHistory = exports.createHashHistory = exports.createHistory = undefined; var _LocationUtils = require('./LocationUtils'); // 判断a、b两个location数据对象是否相同 Object.defineProperty(exports, 'locationsAreEqual', { enumerable: true, get: function get() { return _LocationUtils.locationsAreEqual; } }); // createBrowserHistory(options),构建browserHistory对象,内含变更页面路径到更新location数据到执行绑点函数的一般方法 // options.forceRefresh 强制使用window.location.href(path)或window.location.replace(path)更新页面路径 // 返回值 // { // getUserConfirmation,// getUserConfirmation(message,callback) 在callback回调中定制执行window.confirm(message) // forceRefresh,// 强制使用window.location.href(path)或window.location.replace(path)更新页面路径 // getCurrentLocation,// 获取当前location数据{pathname,search,hash,state,action,key} // pushLocation,// 路径重新赋值,并使用window.sessionStorage存储{[key]:state}形式的location路径数据 // replaceLocation,// 路径重新赋值,并使用window.sessionStorage存储{[key]:state}形式的location路径数据 // listenBefore,// 将transitionTo方法绑定到popState或hashChange事件上,添加前置钩子;事件触发时,执行钩子,及变更浏览器location及window.sessionStorage存储 // listen,// 将transitionTo方法绑定到popState或hashChange事件上,添加后置钩子;事件触发时,执行钩子,及变更浏览器location及window.sessionStorage存储 // transitionTo,// 变更页面路径、更新window.sessionStorage、执行钩子函数,更新allKeys,可作为页面路径变更时的回调 // push,// transitionTo方法变更页面路径、更新window.sessionStorage、执行钩子函数,allKeys添加一条路径记录,可作为页面路径变更时的回调 // replace,// transitionTo方法变更页面路径、更新window.sessionStorage、执行钩子函数,allKeys替换一条路径记录,可作为页面路径变更时的回调 // go,// window.history.go跳转页面 // goBack,// window.history.go跳转页面 // goForward,// window.history.go跳转页面 // createKey,// 随机生成一个key,作为查询字符串中的值,以及window.sessionStorage中的键 // createPath,// 生成路径 // createHref,// 生成路径 // createLocation,// 生成location数据 // } var _createBrowserHistory = require('./createBrowserHistory'); var _createBrowserHistory2 = _interopRequireDefault(_createBrowserHistory); // createHashHistory(options),创建hashHistory对象,内含变更页面路径到更新location数据到执行绑点函数的一般方法 // options.queryKey 不能设置为false,哈希路径中查询字符串的键,值为window.sessionStorage存储state的键 // options.hashType 须是hashbang、noslash、slash中的一个,默认slash,规定哈希路径hashPath类型 // hashbang以"!"起始,noslash直接跟路径,slash以"/"起始 // 返回值 // { // getUserConfirmation,// getUserConfirmation(message,callback) 在callback回调中定制执行window.confirm(message) // queryKey,// 哈希路径中查询字符串的键,值为window.sessionStorage存储state的键 // hashType,// 规定哈希路径hashPath书写形式 // getCurrentLocation,// 获取当前location数据{pathname,search,hash,state,action,key} // pushLocation,// 哈希路径重新赋值,并使用window.sessionStorage存储{[key]:state}形式的location哈希路径数据 // replaceLocation,// 哈希路径重新赋值,并使用window.sessionStorage存储{[key]:state}形式的location哈希路径数据 // listenBefore,// 将transitionTo方法绑定到hashChange事件上,添加前置钩子;事件触发时,执行钩子,及变更浏览器location及window.sessionStorage存储 // listen,// 将transitionTo方法绑定到hashChange事件上,添加后置钩子;事件触发时,执行钩子,及变更浏览器location及window.sessionStorage存储 // transitionTo,// 变更页面路径、更新window.sessionStorage、执行钩子函数,更新allKeys,可作为页面路径变更时的回调 // push,// transitionTo方法变更页面路径、更新window.sessionStorage、执行钩子函数,allKeys添加一条路径记录,可作为页面路径变更时的回调 // replace,// transitionTo方法变更页面路径、更新window.sessionStorage、执行钩子函数,allKeys替换一条路径记录,可作为页面路径变更时的回调 // go,// window.history.go跳转页面 // goBack,// window.history.go跳转页面 // goForward,// window.history.go跳转页面 // createKey,// 随机生成一个key,作为查询字符串中的值,以及window.sessionStorage中的键 // createPath,// 生成路径 // createHref,// 生成哈希路径 // createLocation,// 生成location数据 // } var _createHashHistory2 = require('./createHashHistory'); var _createHashHistory3 = _interopRequireDefault(_createHashHistory2); // createMemoryHistory(options),使用js闭包缓存特点构建{key:state}存储机制,存储在闭包变量storage中 // options.entries options为路径对象{path,search,hash,key,state}构成的数组时,将options赋值给options.entries; // options为字符串时,将[options]赋值给options.entries // options.current 默认取options.entries.length-1 // 返回值 // { // entries,// {path,search,hash,key,state}对象构成的路径数据数组 // getCurrentLocation,// 获取当前location数据{pathname,search,hash,state,action,key} // pushLocation,// entries、storage添加一条路径记录 // replaceLocation,// entries、storage替换一条路径记录 // listenBefore,// 添加后置钩子 // listen,// 添加后置钩子 // transitionTo,// 变更页面路径、更新storage、执行钩子函数,更新allKeys,可作为页面路径变更时的回调 // push,// transitionTo方法变更页面路径、更新storage、执行钩子函数,allKeys添加一条路径记录,可作为页面路径变更时的回调 // replace,// transitionTo方法变更页面路径、更新storage、执行钩子函数,allKeys替换一条路径记录,可作为页面路径变更时的回调 // go,// 变更页面路径、更新storage、执行钩子函数,更新allKeys // goBack,// window.history.go跳转页面 // goForward,// window.history.go跳转页面 // createKey,// 随机生成一个key,作为查询字符串中的值,以及window.sessionStorage中的键 // createPath,// 生成路径 // createHref,// 生成哈希路径 // createLocation,// 生成location数据 // } var _createMemoryHistory2 = require('./createMemoryHistory'); var _createMemoryHistory3 = _interopRequireDefault(_createMemoryHistory2); // 装饰createHistory函数,操作location数据对象时分离basename,返回装饰函数 // 传参可以是createBrowserHistory、createHashHistory、createMemoryHistory var _useBasename2 = require('./useBasename'); var _useBasename3 = _interopRequireDefault(_useBasename2); // 装饰createHistory,添加listenBeforeUnload方法,返回值接受options作为参数,供createHistory(options)调用 // listenBeforeUnload方法,关闭页面时执行listener,触发'beforeunload',listener返回值作为弹出警告,返回移除监听事件函数 // 传参可以是createBrowserHistory、createHashHistory、createMemoryHistory var _useBeforeUnload2 = require('./useBeforeUnload'); var _useBeforeUnload3 = _interopRequireDefault(_useBeforeUnload2); // 同useBasename模块相仿,装饰createHistory函数,操作location数据对象时分离query查询字符串对象,返回装饰函数 // 传参可以是createBrowserHistory、createHashHistory、createMemoryHistory var _useQueries2 = require('./useQueries'); var _useQueries3 = _interopRequireDefault(_useQueries2); // location.action允许的值 var _Actions2 = require('./Actions'); var _Actions = _interopRequireWildcard(_Actions2); // obj为history模块内建模块(对象),原样输出;否则转化为纯对象输出 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } // obj为history模块内建模块(函数),原样输出;否则将函数挂载在default方法上 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.createHistory = _createBrowserHistory2.default; exports.createHashHistory = _createHashHistory3.default; exports.createMemoryHistory = _createMemoryHistory3.default; exports.useBasename = _useBasename3.default; exports.useBeforeUnload = _useBeforeUnload3.default; exports.useQueries = _useQueries3.default; exports.Actions = _Actions;