UNPKG

20.2 kBSource Map (JSON)View Raw
1{"version":3,"file":"persist.min.js","sources":["../src/browser.js","../src/consts.js","../src/storageManager.js","../src/utils.js","../src/Persist.js","../src/index.umd.js"],"sourcesContent":["const win = (typeof window !== `undefined` && window) || {};\n\nexport {win as window};\nexport const console = win.console;\nexport const document = win.document;\nexport const history = win.history;\nexport const location = win.location;\nexport const navigator = win.navigator;\nexport const parseFloat = win.parseFloat;\nexport const performance = win.performance;\n\nlet localStorage = null;\n\nlet sessionStorage = null;\n\ntry {\n\tlocalStorage = win.localStorage;\n\tsessionStorage = win.sessionStorage;\n} catch (e) {\n}\n\nexport {\n\tlocalStorage,\n\tsessionStorage,\n};\n","import {performance} from \"./browser\";\n\nexport const CONST_PERSIST = \"___persist___\";\nexport const CONST_PERSIST_STATE = `state${CONST_PERSIST}`;\nexport const CONST_DEPTHS = \"depths\";\nexport const CONST_LAST_URL = \"lastUrl\";\nconst navigation = performance && performance.navigation;\n\nexport const TYPE_NAVIGATE = (navigation && navigation.TYPE_NAVIGATE) || 0;\nexport const TYPE_RELOAD = (navigation && navigation.TYPE_RELOAD) || 1;\nexport const TYPE_BACK_FORWARD = (navigation && navigation.TYPE_BACK_FORWARD) || 2;\n","import {window, history, location, sessionStorage, localStorage} from \"./browser\";\nimport {CONST_PERSIST} from \"./consts\";\n\nconst isSupportState = history && \"replaceState\" in history && \"state\" in history;\n\nfunction isStorageAvailable(storage) {\n\tif (!storage) {\n\t\treturn undefined;\n\t}\n\tconst TMP_KEY = `__tmp__${CONST_PERSIST}`;\n\n\ttry {\n\t\t// In case of iOS safari private mode, calling setItem on storage throws error\n\t\tstorage.setItem(TMP_KEY, CONST_PERSIST);\n\n\t\t// In Chrome incognito mode, can not get saved value\n\t\t// In IE8, calling storage.getItem occasionally makes \"Permission denied\" error\n\t\treturn storage.getItem(TMP_KEY) === CONST_PERSIST;\n\t} catch (e) {\n\t\treturn false;\n\t}\n}\n\nconst storage = (function() {\n\tlet strg;\n\n\tif (isStorageAvailable(sessionStorage)) {\n\t\tstrg = sessionStorage;\n\t} else if (isStorageAvailable(localStorage)) {\n\t\tstrg = localStorage;\n\t}\n\n\treturn strg;\n})();\n\nfunction warnInvalidStorageValue() {\n\t/* eslint-disable no-console */\n\tconsole.warn(\"window.history or session/localStorage has no valid \" +\n\t\t\t\"format data to be handled in persist.\");\n\t/* eslint-enable no-console */\n}\n\nfunction getStorage() {\n\treturn storage;\n}\n\n/*\n * Get state value\n */\nfunction getState(key) {\n\tlet state;\n\n\tlet stateStr;\n\n\tif (storage) {\n\t\tstateStr = storage.getItem(key);\n\t} else if (history.state) {\n\t\tif (typeof history.state === \"object\" && history.state !== null) {\n\t\t\tstateStr = history.state[key];\n\t\t} else {\n\t\t\twarnInvalidStorageValue();\n\t\t}\n\t} else {\n\t\tstateStr = history.state;\n\t}\n\n\t// the storage is clean\n\tif (stateStr === null) {\n\t\treturn {};\n\t}\n\n\t// \"null\" is not a valid\n\tconst isValidStateStr = typeof stateStr === \"string\" &&\n\t\t\t\t\t\t\t\tstateStr.length > 0 && stateStr !== \"null\";\n\n\ttry {\n\t\tstate = JSON.parse(stateStr);\n\n\t\t// like '[ ... ]', '1', '1.234', '\"123\"' is also not valid\n\t\tconst isValidType = !(typeof state !== \"object\" || state instanceof Array);\n\n\t\tif (!isValidStateStr || !isValidType) {\n\t\t\tthrow new Error();\n\t\t}\n\t} catch (e) {\n\t\twarnInvalidStorageValue();\n\t\tstate = {};\n\t}\n\n\t// Note2 (Android 4.3) return value is null\n\treturn state;\n}\n\nfunction getStateByKey(key, valueKey) {\n\tif (!isSupportState && !storage) {\n\t\treturn undefined;\n\t}\n\n\tlet result = getState(key)[valueKey];\n\n\t// some device returns \"null\" or undefined\n\tif (result === \"null\" || typeof result === \"undefined\") {\n\t\tresult = null;\n\t}\n\treturn result;\n}\n\n/*\n * Set state value\n */\nfunction setState(key, state) {\n\tif (storage) {\n\t\tif (state) {\n\t\t\tstorage.setItem(\n\t\t\t\tkey, JSON.stringify(state));\n\t\t} else {\n\t\t\tstorage.removeItem(key);\n\t\t}\n\t} else {\n\t\ttry {\n\t\t\tconst historyState = !history || history.state == null ? {} : history.state;\n\n\t\t\tif (history && typeof historyState === \"object\") {\n\t\t\t\thistoryState[key] = JSON.stringify(state);\n\t\t\t\thistory.replaceState(\n\t\t\t\t\thistoryState,\n\t\t\t\t\tdocument.title,\n\t\t\t\t\tlocation.href\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t/* eslint-disable no-console */\n\t\t\t\tconsole.warn(\"To use a history object, it must be an object that is not a primitive type.\");\n\t\t\t\t/* eslint-enable no-console */\n\t\t\t}\n\t\t} catch (e) {\n\t\t\t/* eslint-disable no-console */\n\t\t\tconsole.warn(e.message);\n\t\t\t/* eslint-enable no-console */\n\t\t}\n\t}\n\n\tstate ? window[CONST_PERSIST] = true : delete window[CONST_PERSIST];\n}\n\nfunction setStateByKey(key, valueKey, data) {\n\tif (!isSupportState && !storage) {\n\t\treturn;\n\t}\n\n\tconst beforeData = getState(key);\n\n\tbeforeData[valueKey] = data;\n\tsetState(key, beforeData);\n}\n\n/*\n * flush current history state\n */\nfunction reset(key) {\n\tsetState(key, null);\n}\n\nexport {\n\treset,\n\tsetStateByKey,\n\tgetStateByKey,\n\tgetStorage,\n};\n","import {navigator, parseFloat, performance, location} from \"./browser\";\nimport {CONST_PERSIST} from \"./consts\";\n\nconst userAgent = navigator ? navigator.userAgent : \"\";\n\nconst isNeeded = (function() {\n\tconst isIOS = (new RegExp(\"iPhone|iPad\", \"i\")).test(userAgent);\n\tconst isMacSafari = (new RegExp(\"Mac\", \"i\")).test(userAgent) &&\n\t\t!(new RegExp(\"Chrome\", \"i\")).test(userAgent) &&\n\t\t(new RegExp(\"Apple\", \"i\")).test(userAgent);\n\tconst isAndroid = (new RegExp(\"Android \", \"i\")).test(userAgent);\n\tconst isWebview = (new RegExp(\"wv; |inapp;\", \"i\")).test(userAgent);\n\tconst androidVersion = isAndroid ? parseFloat(new RegExp(\n\t\t\"(Android)\\\\s([\\\\d_\\\\.]+|\\\\d_0)\", \"i\"\n\t).exec(userAgent)[2]) : undefined;\n\n\treturn !(isIOS ||\n\t\t\tisMacSafari ||\n\t\t\t(isAndroid &&\n\t\t\t\t((androidVersion <= 4.3 && isWebview) || androidVersion < 3)));\n})();\n\n// In case of IE8, TYPE_BACK_FORWARD is undefined.\nfunction getNavigationType() {\n\treturn performance && performance.navigation &&\n\t\tperformance.navigation.type;\n}\nfunction getUrl() {\n\treturn location ? location.href.split(\"#\")[0] : \"\";\n}\nfunction getStorageKey(name) {\n\treturn name + CONST_PERSIST;\n}\n\nexport {\n\tgetUrl,\n\tgetStorageKey,\n\tgetNavigationType,\n\tisNeeded,\n};\n","/* eslint-disable no-use-before-define */\nimport {\n\treset,\n\tsetStateByKey,\n\tgetStateByKey,\n\tgetStorage,\n} from \"./storageManager\";\nimport {isNeeded, getUrl, getStorageKey, getNavigationType} from \"./utils\";\nimport {console, window} from \"./browser\";\nimport {TYPE_BACK_FORWARD, TYPE_NAVIGATE, CONST_PERSIST_STATE, CONST_DEPTHS, CONST_LAST_URL} from \"./consts\";\n\nlet currentUrl = \"\";\n\n\nfunction execRec(obj, path, func) {\n\tlet _obj = obj;\n\n\tif (!_obj) {\n\t\t_obj = isNaN(path[0]) ? {} : [];\n\t}\n\n\tconst head = path.shift();\n\n\tif (path.length === 0) {\n\t\tif (_obj instanceof Array && isNaN(head)) {\n\t\t\tconsole.warn(\"Don't use key string on array\");\n\t\t}\n\t\tfunc(_obj, head);\n\t\treturn _obj;\n\t}\n\n\t_obj[head] = execRec(_obj[head], path, func);\n\treturn _obj;\n}\n\nfunction setPersistState(key, value) {\n\ttry {\n\t\tsetStateByKey(CONST_PERSIST_STATE, key, value);\n\t} catch (e) {\n\t\tif (clearFirst()) {\n\t\t\tif (key === CONST_LAST_URL) {\n\t\t\t\tsetPersistState(key, value);\n\t\t\t} else if (key === CONST_DEPTHS) {\n\t\t\t\tsetPersistState(key, value && value.slice(1));\n\t\t\t}\n\t\t} else {\n\t\t\t// There is no more size to fit in.\n\t\t\tthrow e;\n\t\t}\n\t}\n}\nfunction getPersistState(key) {\n\treturn getStateByKey(CONST_PERSIST_STATE, key);\n}\nfunction updateDepth(type = 0) {\n\tconst url = getUrl();\n\n\tif (currentUrl === url) {\n\t\treturn;\n\t}\n\t// url is not the same for the first time, pushState, or replaceState.\n\tcurrentUrl = url;\n\tconst depths = getPersistState(CONST_DEPTHS) || [];\n\n\tif (type === TYPE_BACK_FORWARD) {\n\t\t// Change current url only\n\t\tconst currentIndex = depths.indexOf(currentUrl);\n\n\t\t~currentIndex && setPersistState(CONST_LAST_URL, currentUrl);\n\t} else {\n\t\tconst prevLastUrl = getPersistState(CONST_LAST_URL);\n\n\t\treset(getStorageKey(currentUrl));\n\n\t\tif (type === TYPE_NAVIGATE && url !== prevLastUrl) {\n\t\t\t// Remove all url lists with higher index than current index\n\t\t\tconst prevLastIndex = depths.indexOf(prevLastUrl);\n\t\t\tconst removedList = depths.splice(prevLastIndex + 1, depths.length);\n\n\t\t\tremovedList.forEach(removedUrl => {\n\t\t\t\treset(getStorageKey(removedUrl));\n\t\t\t});\n\t\t\t// If the type is NAVIGATE and there is information about current url, delete it.\n\t\t\tconst currentIndex = depths.indexOf(currentUrl);\n\n\t\t\t~currentIndex && depths.splice(currentIndex, 1);\n\t\t}\n\t\t// Add depth for new address.\n\t\tif (depths.indexOf(url) < 0) {\n\t\t\tdepths.push(url);\n\t\t}\n\t\tsetPersistState(CONST_DEPTHS, depths);\n\t\tsetPersistState(CONST_LAST_URL, url);\n\t}\n}\n\nfunction clearFirst() {\n\tconst depths = getPersistState(CONST_DEPTHS) || [];\n\tconst removed = depths.splice(0, 1);\n\n\tif (!removed.length) {\n\t\t// There is an error because there is no depth to add data.\n\t\treturn false;\n\t}\n\tconst removedUrl = removed[0];\n\n\treset(getStorageKey(removedUrl));\n\tif (currentUrl === removedUrl) {\n\t\tcurrentUrl = \"\";\n\t\tsetPersistState(CONST_LAST_URL, \"\");\n\t\tif (!depths.length) {\n\t\t\t// I tried to add myself, but it didn't add up, so I got an error.\n\t\t\treturn false;\n\t\t}\n\t}\n\tsetPersistState(CONST_DEPTHS, depths);\n\t// Clear the previous record and try to add data again.\n\treturn true;\n}\nfunction clear() {\n\tconst depths = getPersistState(CONST_DEPTHS) || [];\n\n\tdepths.forEach(url => {\n\t\treset(getStorageKey(url));\n\t});\n\n\treset(CONST_PERSIST_STATE);\n\n\tcurrentUrl = \"\";\n}\nif (\"onpopstate\" in window) {\n\twindow.addEventListener(\"popstate\", () => {\n\t\t// popstate event occurs when backward or forward\n\t\tupdateDepth(TYPE_BACK_FORWARD);\n\t});\n}\n\n/**\n * Get or store the current state of the web page using JSON.\n * @ko 웹 페이지의 현재 상태를 JSON 형식으로 저장하거나 읽는다.\n * @alias eg.Persist\n *\n * @support {\"ie\": \"9+\", \"ch\" : \"latest\", \"ff\" : \"latest\", \"sf\" : \"latest\" , \"edge\" : \"latest\", \"ios\" : \"7+\", \"an\" : \"2.3+ (except 3.x)\"}\n */\nclass Persist {\n\tstatic VERSION = \"#__VERSION__#\";\n\tstatic StorageManager = {\n\t\treset,\n\t\tsetStateByKey,\n\t\tgetStateByKey,\n\t\tgetStorage,\n\t};\n\t/**\n\t * @static\n\t * Clear all information in Persist\n\t */\n\tstatic clear() {\n\t\tclear();\n\t}\n\t/**\n\t * @static\n\t * Return whether you need \"Persist\" module by checking the bfCache support of the current browser\n\t * @return {Boolean}\n\t */\n\tstatic isNeeded() {\n\t\treturn isNeeded;\n\t}\n\t/**\n\t* Constructor\n\t* @param {String} key The key of the state information to be stored <ko>저장할 상태 정보의 키</ko>\n\t**/\n\tconstructor(key) {\n\t\tthis.key = key || \"\";\n\t}\n\n\t/**\n\t * Read value\n\t * @param {String?} path target path\n\t * @return {String|Number|Boolean|Object|Array}\n\t */\n\tget(path) {\n\t\t// update url for pushState, replaceState\n\t\tupdateDepth(TYPE_NAVIGATE);\n\n\t\t// find path\n\t\tconst urlKey = getStorageKey(getUrl());\n\t\tconst globalState =\tgetStateByKey(urlKey, this.key);\n\n\n\t\tif (!path || path.length === 0) {\n\t\t\treturn globalState;\n\t\t}\n\n\t\tconst pathToken = path.split(\".\");\n\n\t\tlet currentItem = globalState;\n\n\t\tlet isTargetExist = true;\n\n\t\tfor (let i = 0; i < pathToken.length; i++) {\n\t\t\tif (!currentItem) {\n\t\t\t\tisTargetExist = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcurrentItem = currentItem[pathToken[i]];\n\t\t}\n\t\tif (!isTargetExist || currentItem == null) {\n\t\t\treturn null;\n\t\t}\n\t\treturn currentItem;\n\t}\n\t/**\n\t * Save value\n\t * @param {String} path target path\n\t * @param {String|Number|Boolean|Object|Array} value value to save\n\t * @return {Persist}\n\t */\n\tset(path, value) {\n\t\t// update url for pushState, replaceState\n\t\tupdateDepth(TYPE_NAVIGATE);\n\t\t// find path\n\t\tconst key = this.key;\n\t\tconst urlKey = getStorageKey(getUrl());\n\t\tconst globalState =\tgetStateByKey(urlKey, key);\n\n\t\ttry {\n\t\t\tif (path.length === 0) {\n\t\t\t\tsetStateByKey(urlKey, key, value);\n\t\t\t} else {\n\t\t\t\tconst allValue = execRec(globalState, path.split(\".\"), (obj, head) => {\n\t\t\t\t\tobj[head] = value;\n\t\t\t\t});\n\n\t\t\t\tsetStateByKey(\n\t\t\t\t\turlKey,\n\t\t\t\t\tkey,\n\t\t\t\t\tallValue\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tif (clearFirst(e)) {\n\t\t\t\tthis.set(path, value);\n\t\t\t} else {\n\t\t\t\t// There is no more size to fit in.\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\t/**\n\t * Remove value\n\t * @param {String} path target path\n\t * @return {Persist}\n\t */\n\tremove(path) {\n\t\t// update url for pushState, replaceState\n\t\tupdateDepth(TYPE_NAVIGATE);\n\n\t\t// find path\n\t\tconst key = this.key;\n\t\tconst urlKey = getStorageKey(getUrl());\n\t\tconst globalState =\tgetStateByKey(urlKey, key);\n\n\t\ttry {\n\t\t\tif (path.length === 0) {\n\t\t\t\tsetStateByKey(urlKey, key, null);\n\t\t\t} else {\n\t\t\t\tconst value = execRec(globalState, path.split(\".\"), (obj, head) => {\n\t\t\t\t\tif (typeof obj === \"object\") {\n\t\t\t\t\t\tdelete obj[head];\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tsetStateByKey(\n\t\t\t\t\turlKey,\n\t\t\t\t\tkey,\n\t\t\t\t\tvalue\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tif (clearFirst(e)) {\n\t\t\t\tthis.remove(path);\n\t\t\t} else {\n\t\t\t\t// There is no more size to fit in.\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n}\n\n// If navigation's type is not TYPE_BACK_FORWARD, delete information about current url.\nupdateDepth(getNavigationType());\n\nexport {\n\tupdateDepth,\n};\n\nexport default Persist;\n","import Persist, {updateDepth} from \"./Persist\";\n\n// eslint-disable-next-line import/no-named-as-default-member\nPersist.updateDepth = updateDepth;\n\nexport default Persist;\n"],"names":["win","window","console","history","document","location","navigator","parseFloat","performance","localStorage","sessionStorage","e","CONST_PERSIST","CONST_PERSIST_STATE","CONST_DEPTHS","CONST_LAST_URL","navigation","TYPE_NAVIGATE","TYPE_BACK_FORWARD","TYPE_RELOAD","isSupportState","isStorageAvailable","storage","TMP_KEY","setItem","getItem","strg","warnInvalidStorageValue","warn","getStorage","getState","key","state","stateStr","isValidStateStr","length","isValidType","JSON","parse","Array","Error","getStateByKey","valueKey","result","setState","stringify","removeItem","historyState","replaceState","title","href","message","setStateByKey","data","beforeData","reset","isIOS","isMacSafari","isAndroid","isWebview","androidVersion","userAgent","isNeeded","RegExp","test","exec","undefined","getUrl","split","getStorageKey","name","currentUrl","execRec","obj","path","func","_obj","isNaN","head","shift","setPersistState","value","clearFirst","slice","getPersistState","updateDepth","type","url","depths","indexOf","prevLastUrl","prevLastIndex","splice","forEach","removedUrl","currentIndex","push","removed","addEventListener","Persist","clear","get","globalState","this","pathToken","currentItem","isTargetExist","i","set","urlKey","remove","VERSION","StorageManager"],"mappings":"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"}
\No newline at end of file