├── .gitignore ├── README.md ├── package.json └── src ├── decode.ts ├── detect-webp.ts ├── get-all-cookie.ts ├── get-all-query-string.ts ├── get-cookie.ts ├── get-query-string.ts ├── index.ts ├── is-empty-object.ts ├── local-storage.ts ├── object-assign.ts ├── object-to-query.ts ├── raf.ts ├── remove-cookie.ts └── set-cookie.ts /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | .vscode 4 | node_modules 5 | .DS_store 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # util.ts 2 | Utils for mobile browsers, built with TypeScript 3 | 4 | ### Cookies 5 | ``` typescript 6 | setCookie(key: string, value: string): void; 7 | getCookie(key: string): string; 8 | getAllCookie(): Cookies; 9 | removeCookie(key: string): void; 10 | ``` 11 | 12 | ### QueryString 13 | ``` typescript 14 | getQueryString(key: string): string; 15 | getAllQueryString(key: string): QueryStrings; 16 | ``` 17 | 18 | ### Object 19 | ``` typescript 20 | isEmptyObject(obj: Object): boolean; 21 | objectAssign(target: Object, ...args: Object[]): Object; 22 | objectToQuery(obj: Object): string; 23 | ``` 24 | 25 | ### Polyfills 26 | ``` typescript 27 | raf(callback: Function): number; 28 | cancelRaf(id: number): void; 29 | ``` 30 | 31 | ### Others 32 | ``` typescript 33 | decode(value: string): string; 34 | detectWebp(callback: (result: boolean) => void); 35 | ``` 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "util-ts", 3 | "version": "1.0.0", 4 | "description": "Utils for mobile browsers, built with TypeScript", 5 | "main": "src/index.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "devDependencies": { 10 | }, 11 | "scripts": { 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/chenjiahan/never-utils.git" 16 | }, 17 | "author": "neverland", 18 | "license": "ISC", 19 | "bugs": { 20 | "url": "https://github.com/chenjiahan/never-utils/issues" 21 | }, 22 | "homepage": "https://github.com/chenjiahan/never-utils#readme" 23 | } 24 | -------------------------------------------------------------------------------- /src/decode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 安全 decode 3 | * 4 | * ### Example 5 | * ``` 6 | * const value = decode('C%9E5%H__a100373__b4'); 7 | * ``` 8 | */ 9 | 10 | export function decode(value: string): string { 11 | try { 12 | return decodeURIComponent(value); 13 | } catch (e) { 14 | return void 0; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/detect-webp.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 判断是否支持 webp (异步方法) 3 | * 4 | * ### Example 5 | * ``` 6 | * detectWebp(result => console.log(result)); 7 | * ``` 8 | */ 9 | 10 | import { LS } from './local-storage'; 11 | 12 | let support: boolean; 13 | 14 | export function detectWebp(callback: (result: boolean) => void): void { 15 | 16 | if (support === void 0) { 17 | const local = LS.get('supportWebp'); 18 | support = local === 'true' ? true : local === 'false' ? false : void 0; 19 | } 20 | 21 | if (support !== void 0) { 22 | return callback(support); 23 | } 24 | 25 | const img = new Image(); 26 | img.onload = () => { 27 | support = img.width > 0 && img.height > 0; 28 | LS.set('supportWebp', support); 29 | callback(support); 30 | }; 31 | img.onerror = () => { 32 | support = false; 33 | LS.set('supportWebp', support); 34 | callback(support); 35 | }; 36 | img.src = 'data:image/webp;base64,UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA=='; 37 | } 38 | -------------------------------------------------------------------------------- /src/get-all-cookie.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 获取所有 cookie 3 | * 4 | * ### Example 5 | * ``` 6 | * const cookies = getAllCookie(); 7 | * const { uuid, token, userid } = cookies; 8 | * ``` 9 | */ 10 | 11 | import { decode } from './decode'; 12 | 13 | export type Cookies = { 14 | [key: string]: string; 15 | }; 16 | 17 | export function getAllCookie(): Cookies { 18 | const cookies = document.cookie.split('; '); 19 | const result = {}; 20 | for (let i = 0, l = cookies.length; i < l; i++) { 21 | const item = cookies[i].split('='); 22 | const key = item.shift(); 23 | result[key] = decode(item.join('=')); 24 | } 25 | return result; 26 | } 27 | -------------------------------------------------------------------------------- /src/get-all-query-string.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 获取所有 query string 3 | * 4 | * ### Example 5 | * ``` 6 | * const queryString = getAllQueryString(); 7 | * const { token, entry, version } = queryString; 8 | * ``` 9 | */ 10 | 11 | import { decode } from './decode'; 12 | 13 | export type QueryStrings = { 14 | [key: string]: string; 15 | }; 16 | 17 | export function getAllQueryString(): QueryStrings { 18 | const arr = location.search.substr(1).split('&'); 19 | const result = {}; 20 | for (let i = 0, l = arr.length; i < l; i++) { 21 | const item = arr[i].split('='); 22 | const key = item.shift(); 23 | result[key] = decode(item.join('=')); 24 | } 25 | return result; 26 | } 27 | -------------------------------------------------------------------------------- /src/get-cookie.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 读取 cookie 3 | * 4 | * ### Example 5 | * ``` 6 | * const uuid = getCookie('uuid'); 7 | * const token = getCookie('token'); 8 | * ``` 9 | */ 10 | 11 | import { decode } from './decode'; 12 | 13 | export function getCookie(name: string): string { 14 | const arr = document.cookie.split('; '); 15 | for (let i = 0, l = arr.length; i < l; i++) { 16 | const item = arr[i].split('='); 17 | if (item.shift() === name) { 18 | return decode(item.join('=')); 19 | } 20 | } 21 | return ''; 22 | } 23 | -------------------------------------------------------------------------------- /src/get-query-string.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 获取 query string 3 | * 4 | * ### Example 5 | * ``` 6 | * const token = getQueryString('token'); 7 | * const entry = getQueryString('entry'); 8 | * ``` 9 | */ 10 | 11 | import { decode } from './decode'; 12 | 13 | export function getQueryString(name: string): string { 14 | const arr = location.search.substr(1).split('&'); 15 | for (let i = 0, l = arr.length; i < l; i++) { 16 | const item = arr[i].split('='); 17 | if (item.shift() === name) { 18 | return decode(item.join('=')); 19 | } 20 | } 21 | return ''; 22 | } 23 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './decode'; 2 | export * from './detect-webp'; 3 | export * from './get-all-cookie'; 4 | export * from './get-all-query-string'; 5 | export * from './get-cookie'; 6 | export * from './get-query-string'; 7 | export * from './is-empty-object'; 8 | export * from './local-storage'; 9 | export * from './object-assign'; 10 | export * from './object-to-query'; 11 | export * from './raf'; 12 | export * from './remove-cookie'; 13 | export * from './set-cookie'; 14 | -------------------------------------------------------------------------------- /src/is-empty-object.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 是否为空对象 3 | * 4 | * ### Example 5 | * ``` 6 | * isEmptyObject({}); // => true 7 | * isEmptyObject({ a: 1 }) // => false 8 | * ``` 9 | */ 10 | 11 | export function isEmptyObject(obj: Object): boolean { 12 | return Object.keys(obj).length === 0; 13 | } 14 | -------------------------------------------------------------------------------- /src/local-storage.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * localStorage 操作 3 | * 4 | * ### Example 5 | * ``` 6 | * LS.set('name', 'coder'); 7 | * LS.get('name'); 8 | * LS.remove('name'); 9 | * ``` 10 | */ 11 | 12 | const ls = window.localStorage; 13 | 14 | export const LS = { 15 | set(key: string, value: any): boolean { 16 | if (ls) { 17 | try { 18 | ls.setItem(key, value); 19 | return true; 20 | } catch (e) { 21 | e.code === 22 && ls.clear(); 22 | } 23 | } 24 | return false; 25 | }, 26 | 27 | get(key: string): string { 28 | return ls ? ls.getItem(key) : void 0; 29 | }, 30 | 31 | remove(key: string): void { 32 | ls && ls.removeItem(key); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /src/object-assign.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 合并对象(浅拷贝) 3 | * 4 | * ### Example 5 | * ``` 6 | * objectAssign({}, { a: 1, b: 1 }, { b: 2, c: 3 }); // { a: 1, b: 2, c: 3 } 7 | * ``` 8 | */ 9 | 10 | const hasOwnProperty = Object.prototype.hasOwnProperty; 11 | 12 | function fallback(to: Object, ...args: Object[]): Object { 13 | args.forEach(from => { 14 | for (let key in from) { 15 | if (hasOwnProperty.call(from, key)) { 16 | to[key] = from[key]; 17 | } 18 | } 19 | }); 20 | return to; 21 | } 22 | 23 | export const objectAssign = Object.assign || fallback; 24 | -------------------------------------------------------------------------------- /src/object-to-query.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 对象转 query string 3 | * 4 | * ### Example 5 | * ``` 6 | * const str = ObjectToQuery({ 7 | * a: 'name', 8 | * b: 123, 9 | * c: 'a b - c' 10 | * }); 11 | * ``` 12 | */ 13 | 14 | export function objectToQuery(obj: Object): string { 15 | return Object.keys(obj).map(key => 16 | key + '=' + encodeURIComponent(obj[key] === void 0 ? '' : obj[key]) 17 | ).join('&'); 18 | } 19 | -------------------------------------------------------------------------------- /src/raf.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * requestAnimationFrame polyfill 3 | * 4 | * ### Example 5 | * ``` 6 | * const id = raf(() => {}); 7 | * cancelRaf(id); 8 | * ``` 9 | */ 10 | 11 | let prev = Date.now(); 12 | function fallback(fn: Function): number { 13 | const curr = Date.now(); 14 | const ms = Math.max(0, 16 - (curr - prev)); 15 | const id = setTimeout(fn, ms); 16 | prev = curr + ms; 17 | return id; 18 | }; 19 | 20 | const self = window; 21 | 22 | const iRaf = self.requestAnimationFrame 23 | || self.webkitRequestAnimationFrame 24 | || fallback; 25 | 26 | const iCancel = self.cancelAnimationFrame 27 | || self.webkitCancelAnimationFrame 28 | || self.clearTimeout; 29 | 30 | export function raf(fn: Function): number { 31 | return iRaf.call(self, fn); 32 | } 33 | 34 | export function cancel(id: number): void { 35 | iCancel.call(self, id); 36 | } 37 | -------------------------------------------------------------------------------- /src/remove-cookie.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 销毁 cookie 3 | * 4 | * ### Example 5 | * ``` 6 | * setCookie('username', 'neverland'); 7 | * removeCookie('username'); 8 | * ``` 9 | */ 10 | 11 | export function removeCookie(key: string): void { 12 | document.cookie = key + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT'; 13 | } 14 | -------------------------------------------------------------------------------- /src/set-cookie.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 设置 cookie 3 | * 4 | * ### Example 5 | * ``` 6 | * setCookie('name', 'neverland'); 7 | * ``` 8 | */ 9 | 10 | export function setCookie(key: string, value: string): void { 11 | document.cookie = key + '=' + encodeURIComponent(value) + '; '; 12 | } 13 | --------------------------------------------------------------------------------