├── .github └── workflows │ └── npmpublish.yml ├── .gitignore ├── .vscode └── settings.json ├── Array ├── .gitkeep ├── from.js └── reduce.js ├── Function └── .gitkeep ├── LICENSE ├── Object └── assign.js ├── README.md ├── String └── .gitkeep ├── bin └── concat.js ├── index.js ├── package-lock.json ├── package.json └── test └── array.from.test.jsx /.github/workflows/npmpublish.yml: -------------------------------------------------------------------------------- 1 | name: Node.js Package 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v1 12 | - uses: actions/setup-node@v1 13 | with: 14 | node-version: 12 15 | - run: npm ci 16 | - run: npm test 17 | publish-npm: 18 | needs: build 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v1 22 | - uses: actions/setup-node@v1 23 | with: 24 | node-version: 12 25 | registry-url: https://registry.npmjs.org/ 26 | - run: npm ci 27 | - run: npm publish 28 | env: 29 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 30 | 31 | publish-gpr: 32 | needs: build 33 | runs-on: ubuntu-latest 34 | steps: 35 | - uses: actions/checkout@v1 36 | - uses: actions/setup-node@v1 37 | with: 38 | node-version: 12 39 | registry-url: https://npm.pkg.github.com/ 40 | scope: '@your-github-username' 41 | - run: npm ci 42 | - run: npm publish 43 | env: 44 | NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "workbench.colorCustomizations": { 3 | "activityBar.background": "#38d93f", 4 | "activityBar.activeBorder": "#645ee0", 5 | "activityBar.foreground": "#15202b", 6 | "activityBar.inactiveForeground": "#15202b99", 7 | "activityBarBadge.background": "#645ee0", 8 | "activityBarBadge.foreground": "#e7e7e7", 9 | "titleBar.activeBackground": "#24ba2a", 10 | "titleBar.inactiveBackground": "#24ba2a99", 11 | "titleBar.activeForeground": "#e7e7e7", 12 | "titleBar.inactiveForeground": "#e7e7e799", 13 | "statusBar.background": "#24ba2a", 14 | "statusBarItem.hoverBackground": "#38d93f", 15 | "statusBar.foreground": "#e7e7e7" 16 | }, 17 | "peacock.color": "#24ba2a" 18 | } -------------------------------------------------------------------------------- /Array/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExtendScript/extendscript-es6-shim/eadc112dc3ec519f22f275580d576bcff7f7686b/Array/.gitkeep -------------------------------------------------------------------------------- /Array/from.js: -------------------------------------------------------------------------------- 1 | // Production steps of ECMA-262, Edition 6, 22.1.2.1 2 | if (!Array.from) { 3 | Array.from = (function () { 4 | var toStr = Object.prototype.toString; 5 | var isCallable = function (fn) { 6 | return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; 7 | }; 8 | var toInteger = function (value) { 9 | var number = Number(value); 10 | if (isNaN(number)) { return 0; } 11 | if (number === 0 || !isFinite(number)) { return number; } 12 | return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); 13 | }; 14 | var maxSafeInteger = Math.pow(2, 53) - 1; 15 | var toLength = function (value) { 16 | var len = toInteger(value); 17 | return Math.min(Math.max(len, 0), maxSafeInteger); 18 | }; 19 | 20 | // The length property of the from method is 1. 21 | return function from(arrayLike/*, mapFn, thisArg */) { 22 | // 1. Let C be the this value. 23 | var C = this; 24 | 25 | // 2. Let items be ToObject(arrayLike). 26 | var items = Object(arrayLike); 27 | 28 | // 3. ReturnIfAbrupt(items). 29 | if (arrayLike == null) { 30 | throw new TypeError('Array.from requires an array-like object - not null or undefined'); 31 | } 32 | 33 | // 4. If mapfn is undefined, then let mapping be false. 34 | var mapFn = arguments.length > 1 ? arguments[1] : void undefined; 35 | var T; 36 | if (typeof mapFn !== 'undefined') { 37 | // 5. else 38 | // 5. a If IsCallable(mapfn) is false, throw a TypeError exception. 39 | if (!isCallable(mapFn)) { 40 | throw new TypeError('Array.from: when provided, the second argument must be a function'); 41 | } 42 | 43 | // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined. 44 | if (arguments.length > 2) { 45 | T = arguments[2]; 46 | } 47 | } 48 | 49 | // 10. Let lenValue be Get(items, "length"). 50 | // 11. Let len be ToLength(lenValue). 51 | var len = toLength(items.length); 52 | 53 | // 13. If IsConstructor(C) is true, then 54 | // 13. a. Let A be the result of calling the [[Construct]] internal method 55 | // of C with an argument list containing the single item len. 56 | // 14. a. Else, Let A be ArrayCreate(len). 57 | var A = isCallable(C) ? Object(new C(len)) : new Array(len); 58 | 59 | // 16. Let k be 0. 60 | var k = 0; 61 | // 17. Repeat, while k < len… (also steps a - h) 62 | var kValue; 63 | while (k < len) { 64 | kValue = items[k]; 65 | if (mapFn) { 66 | A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); 67 | } else { 68 | A[k] = kValue; 69 | } 70 | k += 1; 71 | } 72 | // 18. Let putStatus be Put(A, "length", len, true). 73 | A.length = len; 74 | // 20. Return A. 75 | return A; 76 | }; 77 | }()); 78 | } 79 | -------------------------------------------------------------------------------- /Array/reduce.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Source of the polyfill: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#Polyfill 4 | 5 | */ 6 | 7 | if(!Array.prototype.reduce){ 8 | 9 | Array.prototype.reduce = function(callback) { 10 | 'use strict'; 11 | if (this == null) { 12 | throw new TypeError('Array.prototype.reduce called on null or undefined'); 13 | } 14 | if (typeof callback !== 'function') { 15 | throw new TypeError(callback + ' is not a function'); 16 | } 17 | var t = Object(this), len = t.length >>> 0, k = 0, value; 18 | if (arguments.length == 2) { 19 | value = arguments[1]; 20 | } else { 21 | while (k < len && !(k in t)) { 22 | k++; 23 | } 24 | if (k >= len) { 25 | throw new TypeError('Reduce of empty array with no initial value'); 26 | } 27 | value = t[k++]; 28 | } 29 | for (; k < len; k++) { 30 | if (k in t) { 31 | value = callback(value, t[k], k, t); 32 | } 33 | } 34 | return value; 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /Function/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExtendScript/extendscript-es6-shim/eadc112dc3ec519f22f275580d576bcff7f7686b/Function/.gitkeep -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 ExtendScript 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Object/assign.js: -------------------------------------------------------------------------------- 1 | /** 2 | * https://gist.github.com/WebReflection/10404826 3 | */ 4 | /* eslint no-use-before-define: off */ 5 | 6 | try { 7 | Object.assign({}, {foo: 'bar'}); 8 | }catch(err) { 9 | // failed: so we're in IE8 10 | (function() { 11 | Object.assign = (function(has) { 12 | 'use strict'; 13 | return assign; 14 | function assign(target, source) { 15 | for (var i = 1; i < arguments.length; i++) { 16 | copy(target, arguments[i]); 17 | } 18 | return target; 19 | } 20 | function copy(target, source) { 21 | for (var key in source) { 22 | if (has.call(source, key)) { 23 | target[key] = source[key]; 24 | } 25 | } 26 | } 27 | }({}.hasOwnProperty)); 28 | }()); 29 | } 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # extendscript-es6-shim 2 | A collection of ES6 shims for polyfiling Exendscript (for es5 shims take a look at https://github.com/ExtendScript/extendscript-es5-shim) 3 | 4 | ## Installation 5 | 6 | Currently you can install the package using npm: 7 | 8 | npm init -y 9 | npm install extendscript-es6-shim 10 | 11 | ## Usage 12 | 13 | ## Array, String and Function notes 14 | All polyfills could be used in your code. 15 | 16 | 59 | 60 | ## Development 61 | 62 | - Install the devDependencies by running `npm install` 63 | - Bundle the index.js by running `npm run bundle` 64 | - Add new prototypes in the respective folders 65 | - If you need new folders, add the folder to the top of `./bin/concat.js` into the `folders` array 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /String/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExtendScript/extendscript-es6-shim/eadc112dc3ec519f22f275580d576bcff7f7686b/String/.gitkeep -------------------------------------------------------------------------------- /bin/concat.js: -------------------------------------------------------------------------------- 1 | const folders = ['./Array/', './Function/', './Object/', './String/']; 2 | const fs = require('fs'); 3 | const path = require('path'); 4 | const cat = require('cat'); 5 | const bundlePath = path.resolve(process.cwd(), './index.js'); 6 | // clear the file 7 | fs.writeFileSync(path.resolve(process.cwd(), bundlePath), ''); 8 | // loop folders 9 | folders.forEach(folder => { 10 | fs.readdir(folder, (err, files) => { 11 | files.forEach(file => { 12 | let filePath = path.resolve(process.cwd(), `${folder}${file}`); 13 | if(file === '.gitkeep') { 14 | return; 15 | } 16 | cat(filePath, (error, data)=>{ 17 | if(error !== null) { 18 | console.log(error); 19 | process.exit(); 20 | } 21 | fs.appendFileSync(bundlePath, `//${file}\n${data}\n`); 22 | }); 23 | }); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | //from.js 2 | // Production steps of ECMA-262, Edition 6, 22.1.2.1 3 | if (!Array.from) { 4 | Array.from = (function () { 5 | var toStr = Object.prototype.toString; 6 | var isCallable = function (fn) { 7 | return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; 8 | }; 9 | var toInteger = function (value) { 10 | var number = Number(value); 11 | if (isNaN(number)) { return 0; } 12 | if (number === 0 || !isFinite(number)) { return number; } 13 | return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); 14 | }; 15 | var maxSafeInteger = Math.pow(2, 53) - 1; 16 | var toLength = function (value) { 17 | var len = toInteger(value); 18 | return Math.min(Math.max(len, 0), maxSafeInteger); 19 | }; 20 | 21 | // The length property of the from method is 1. 22 | return function from(arrayLike/*, mapFn, thisArg */) { 23 | // 1. Let C be the this value. 24 | var C = this; 25 | 26 | // 2. Let items be ToObject(arrayLike). 27 | var items = Object(arrayLike); 28 | 29 | // 3. ReturnIfAbrupt(items). 30 | if (arrayLike == null) { 31 | throw new TypeError('Array.from requires an array-like object - not null or undefined'); 32 | } 33 | 34 | // 4. If mapfn is undefined, then let mapping be false. 35 | var mapFn = arguments.length > 1 ? arguments[1] : void undefined; 36 | var T; 37 | if (typeof mapFn !== 'undefined') { 38 | // 5. else 39 | // 5. a If IsCallable(mapfn) is false, throw a TypeError exception. 40 | if (!isCallable(mapFn)) { 41 | throw new TypeError('Array.from: when provided, the second argument must be a function'); 42 | } 43 | 44 | // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined. 45 | if (arguments.length > 2) { 46 | T = arguments[2]; 47 | } 48 | } 49 | 50 | // 10. Let lenValue be Get(items, "length"). 51 | // 11. Let len be ToLength(lenValue). 52 | var len = toLength(items.length); 53 | 54 | // 13. If IsConstructor(C) is true, then 55 | // 13. a. Let A be the result of calling the [[Construct]] internal method 56 | // of C with an argument list containing the single item len. 57 | // 14. a. Else, Let A be ArrayCreate(len). 58 | var A = isCallable(C) ? Object(new C(len)) : new Array(len); 59 | 60 | // 16. Let k be 0. 61 | var k = 0; 62 | // 17. Repeat, while k < len… (also steps a - h) 63 | var kValue; 64 | while (k < len) { 65 | kValue = items[k]; 66 | if (mapFn) { 67 | A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); 68 | } else { 69 | A[k] = kValue; 70 | } 71 | k += 1; 72 | } 73 | // 18. Let putStatus be Put(A, "length", len, true). 74 | A.length = len; 75 | // 20. Return A. 76 | return A; 77 | }; 78 | }()); 79 | } 80 | 81 | //reduce.js 82 | /* 83 | Source of the polyfill: 84 | https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#Polyfill 85 | 86 | */ 87 | 88 | if(!Array.prototype.reduce){ 89 | 90 | Array.prototype.reduce = function(callback) { 91 | 'use strict'; 92 | if (this == null) { 93 | throw new TypeError('Array.prototype.reduce called on null or undefined'); 94 | } 95 | if (typeof callback !== 'function') { 96 | throw new TypeError(callback + ' is not a function'); 97 | } 98 | var t = Object(this), len = t.length >>> 0, k = 0, value; 99 | if (arguments.length == 2) { 100 | value = arguments[1]; 101 | } else { 102 | while (k < len && !(k in t)) { 103 | k++; 104 | } 105 | if (k >= len) { 106 | throw new TypeError('Reduce of empty array with no initial value'); 107 | } 108 | value = t[k++]; 109 | } 110 | for (; k < len; k++) { 111 | if (k in t) { 112 | value = callback(value, t[k], k, t); 113 | } 114 | } 115 | return value; 116 | }; 117 | } 118 | //assign.js 119 | /** 120 | * https://gist.github.com/WebReflection/10404826 121 | */ 122 | /* eslint no-use-before-define: off */ 123 | 124 | try { 125 | Object.assign({}, {foo: 'bar'}); 126 | }catch(err) { 127 | // failed: so we're in IE8 128 | (function() { 129 | Object.assign = (function(has) { 130 | 'use strict'; 131 | return assign; 132 | function assign(target, source) { 133 | for (var i = 1; i < arguments.length; i++) { 134 | copy(target, arguments[i]); 135 | } 136 | return target; 137 | } 138 | function copy(target, source) { 139 | for (var key in source) { 140 | if (has.call(source, key)) { 141 | target[key] = source[key]; 142 | } 143 | } 144 | } 145 | }({}.hasOwnProperty)); 146 | }()); 147 | } 148 | 149 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "extendscript-es6-shim", 3 | "version": "0.2.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "cat": { 8 | "version": "0.2.0", 9 | "resolved": "https://registry.npmjs.org/cat/-/cat-0.2.0.tgz", 10 | "integrity": "sha1-/YUM2n1BYuaQTzO3/PdDsSQ/1DQ=", 11 | "dev": true 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "extendscript-es6-shim", 3 | "version": "0.2.0", 4 | "description": "a collection of useful es6-shims for Extendscript", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 0", 8 | "bundle": "node bin/concat.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/ExtendScript/extendscript-es6-shim.git" 13 | }, 14 | "keywords": [ 15 | "Extendscript", 16 | "ES6", 17 | "shim", 18 | "sham", 19 | "prototype" 20 | ], 21 | "contributers": [ 22 | "Fabian Morón Zirfas (http://fabianmoronzirfas.me)", 23 | "EugenTepin", 24 | "andyinabox", 25 | "Michael J. Ryan (https://github.com/tracker1)" 26 | ], 27 | "license": "MIT", 28 | "bugs": { 29 | "url": "https://github.com/ExtendScript/extendscript-es6-shim/issues" 30 | }, 31 | "homepage": "https://github.com/ExtendScript/extendscript-es6-shim#readme", 32 | "devDependencies": { 33 | "cat": "^0.2.0" 34 | }, 35 | "directories": { 36 | "test": "test" 37 | }, 38 | "dependencies": {} 39 | } 40 | -------------------------------------------------------------------------------- /test/array.from.test.jsx: -------------------------------------------------------------------------------- 1 | #include "../Array/from.js" 2 | $.writeln(Array.from("foo")); 3 | // => f,o,o 4 | #target "indesign" 5 | var doc = app.documents.add(); 6 | doc.pages.add(); 7 | $.writeln(Array.from()); 8 | // => [object Page], [object Page] 9 | --------------------------------------------------------------------------------