├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .jshintrc ├── .npmignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── dist ├── morphdom-esm.js ├── morphdom-factory.js ├── morphdom-umd.js ├── morphdom-umd.min.js └── morphdom.js ├── docs ├── old-benchmark.md └── virtual-dom.md ├── examples ├── .gitignore ├── README.md ├── index.marko ├── lifecycle-events │ ├── browser.json │ ├── client.js │ ├── remove.svg │ ├── style.css │ ├── template.marko │ └── todos.marko ├── package.json ├── server.js └── simple │ ├── browser.json │ ├── client.js │ ├── content-after.marko │ ├── content-before.marko │ ├── style.css │ └── template.marko ├── factory.js ├── index.d.ts ├── package-lock.json ├── package.json ├── src ├── .jshintrc ├── index.js ├── morphAttrs.js ├── morphdom.js ├── specialElHandlers.js └── util.js └── test ├── .jshintrc ├── browser ├── benchmark-results.marko ├── benchmark.js ├── test-result.marko └── test.js ├── fixtures ├── autotest │ ├── attr-value-empty-string │ │ ├── from.html │ │ └── to.html │ ├── change-tagname-ids │ │ ├── from.html │ │ └── to.html │ ├── change-tagname │ │ ├── from.html │ │ └── to.html │ ├── data-table │ │ ├── from.html │ │ └── to.html │ ├── data-table2 │ │ ├── from.html │ │ └── to.html │ ├── equal │ │ ├── from.html │ │ └── to.html │ ├── id-change-tag-name │ │ ├── from.html │ │ └── to.html │ ├── ids-nested-2 │ │ ├── from.html │ │ └── to.html │ ├── ids-nested-3 │ │ ├── from.html │ │ └── to.html │ ├── ids-nested-4 │ │ ├── from.html │ │ └── to.html │ ├── ids-nested-5 │ │ ├── from.html │ │ └── to.html │ ├── ids-nested-6 │ │ ├── from.html │ │ └── to.html │ ├── ids-nested-7 │ │ ├── from.html │ │ └── to.html │ ├── ids-nested │ │ ├── from.html │ │ └── to.html │ ├── ids-prepend │ │ ├── from.html │ │ └── to.html │ ├── input-element-disabled │ │ ├── from.html │ │ ├── index.js │ │ └── to.html │ ├── input-element-enabled │ │ ├── from.html │ │ ├── index.js │ │ └── to.html │ ├── input-element │ │ ├── from.html │ │ └── to.html │ ├── large │ │ ├── from.html │ │ └── to.html │ ├── lengthen │ │ ├── from.html │ │ └── to.html │ ├── one │ │ ├── from.html │ │ └── to.html │ ├── reverse-ids │ │ ├── from.html │ │ └── to.html │ ├── reverse │ │ ├── from.html │ │ └── to.html │ ├── select-element-default │ │ ├── from.html │ │ ├── index.js │ │ └── to.html │ ├── select-element │ │ ├── from.html │ │ ├── index.js │ │ └── to.html │ ├── shorten │ │ ├── from.html │ │ └── to.html │ ├── simple-ids │ │ ├── from.html │ │ └── to.html │ ├── simple-text-el │ │ ├── from.html │ │ └── to.html │ ├── simple │ │ ├── from.html │ │ └── to.html │ ├── svg-append-new │ │ ├── from.html │ │ └── to.html │ ├── svg-append │ │ ├── from.html │ │ └── to.html │ ├── svg-no-default-namespace │ │ ├── from.html │ │ └── to.html │ ├── svg-xlink │ │ ├── from.html │ │ └── to.html │ ├── svg │ │ ├── from.html │ │ └── to.html │ ├── tag-to-text │ │ ├── from.html │ │ └── to.html │ ├── text-to-tag │ │ ├── from.html │ │ └── to.html │ ├── text-to-text │ │ ├── from.html │ │ └── to.html │ ├── textarea │ │ ├── from.html │ │ └── to.html │ ├── todomvc │ │ ├── from.html │ │ └── to.html │ ├── todomvc2 │ │ ├── from.html │ │ └── to.html │ └── two │ │ ├── from.html │ │ └── to.html ├── change-types │ ├── from.html │ └── to.html └── reverse-ids │ ├── from.html │ └── to.html └── mocha-headless ├── .gitignore ├── browser.json ├── mocha-browser-setup.js ├── run.js ├── style.css └── test-page.marko /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | pull_request: 6 | branches: 7 | - master 8 | 9 | jobs: 10 | npm_test: 11 | name: npm test 12 | 13 | strategy: 14 | matrix: 15 | include: 16 | - node: 16.x 17 | 18 | runs-on: ubuntu-latest 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v4 22 | 23 | - name: Set up Node.js ${{ matrix.node }} 24 | uses: actions/setup-node@v4 25 | with: 26 | node-version: ${{ matrix.node }} 27 | 28 | - name: Restore npm cache 29 | uses: actions/cache@v4 30 | with: 31 | path: ~/.npm 32 | key: ${{ runner.os }}-${{ matrix.node }}-node-${{ hashFiles('**/package-lock.json') }} 33 | restore-keys: | 34 | ${{ runner.os }}-${{ matrix.node }}-node- 35 | 36 | - name: npm install and test 37 | run: | 38 | npm install 39 | npm test 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /work 2 | /build 3 | /.idea/ 4 | /npm-debug.log 5 | /node_modules 6 | /*.sublime-workspace 7 | *.orig 8 | .DS_Store 9 | coverage 10 | *.marko.js 11 | /.cache 12 | /test/mocha-headless/generated 13 | /test/mocha-headless/.cache 14 | .cache 15 | ~* 16 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | 4 | ], 5 | 6 | "globals": { 7 | "define": true, 8 | "require": true 9 | }, 10 | 11 | "node" : true, 12 | "esversion" : 6, 13 | "browser" : true, 14 | "boss" : false, 15 | "curly": false, 16 | "debug": false, 17 | "devel": false, 18 | "eqeqeq": true, 19 | "evil": true, 20 | "forin": false, 21 | "immed": true, 22 | "laxbreak": false, 23 | "newcap": true, 24 | "noarg": true, 25 | "noempty": false, 26 | "nonew": true, 27 | "nomen": false, 28 | "onevar": false, 29 | "plusplus": false, 30 | "regexp": false, 31 | "undef": true, 32 | "sub": false, 33 | "white": false, 34 | "eqeqeq": false, 35 | "latedef": false, 36 | "unused": "vars", 37 | "jquery": false, 38 | "strict": false, 39 | "eqnull": true 40 | } 41 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /test 2 | .* 3 | /node_modules 4 | /work 5 | /build 6 | /.idea/ 7 | /npm-debug.log 8 | /node_modules 9 | /*.sublime-workspace 10 | *.orig 11 | .DS_Store 12 | coverage 13 | *.marko.js 14 | /.cache 15 | /examples 16 | ~* -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | sudo: false 4 | 5 | node_js: 6 | - "node" 7 | - "10" 8 | 9 | install: 10 | - npm install 11 | 12 | script: "npm run test" 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | # 2.x 5 | 6 | ## 2.7.5 7 | - Fix issue where empty optgroup in select prevents proper diffing 8 | 9 | ## 2.7.4 10 | - Fix incorrect index references when returning a cloned tree from onBeforeElUpdated 11 | 12 | ## 2.7.3 13 | - Allow returning a new fromEl tree from onBeforeElUpdated to be used morph for that branch 14 | 15 | ## 2.7.2 16 | - Fix morphing duplicate ids of incompatible tags 17 | 18 | ## 2.7.1 19 | - Pass toEl as second argument to `skipFromChildren` callback 20 | 21 | ## 2.7.0 22 | 23 | - Add new `addChild` and `skipFromChildren` callbacks to allow customization of how new children are 24 | added to a parent as well as preserving the from tree when indexing changes for diffing. 25 | 26 | ## 2.5.12 27 | 28 | - Fix merge attrs with multiple properties [PR #175](https://github.com/patrick-steele-idem/morphdom/pull/175) 29 | 30 | ## 2.5.11 31 | 32 | - Multiple forms duplication [PR #174](https://github.com/patrick-steele-idem/morphdom/pull/174) 33 | 34 | ## 2.5.10 35 | 36 | - Pr/167 - Allow document fragment patching [PR #168](https://github.com/patrick-steele-idem/morphdom/pull/168) 37 | 38 | ## 2.5.9 39 | 40 | - Faster attrs merge [PR #165](https://github.com/patrick-steele-idem/morphdom/pull/165) 41 | 42 | ## 2.5.8 43 | 44 | - Minor improvements [PR #164](https://github.com/patrick-steele-idem/morphdom/pull/164) 45 | 46 | ## 2.5.7 47 | 48 | - Chore: Alternate refactor to #155 - Move isSameNode check [PR #156](https://github.com/patrick-steele-idem/morphdom/pull/156) 49 | - Use attribute name with the prefix in XMLNS namespace [PR #133](https://github.com/patrick-steele-idem/morphdom/pull/133) 50 | 51 | ## 2.5.6 52 | 53 | - fixed the string with space trouble [PR #161](https://github.com/patrick-steele-idem/morphdom/pull/161) 54 | 55 | ## 2.5.5 56 | 57 | - Template support for creating element from string [PR #159](https://github.com/patrick-steele-idem/morphdom/pull/159) 58 | 59 | ## 2.5.4 60 | 61 | - Enhancement: Fix id key removal from tree when the element with key is inside a document fragment node (ex: shadow dom) [PR #119](https://github.com/patrick-steele-idem/morphdom/pull/119) 62 | - Minor: small refactor to morphEl to own function [PR #149](small refactor to morphEl to own function) 63 | - selectNode for range b/c documentElement not avail in Safari [commit](https://github.com/patrick-steele-idem/morphdom/commit/6afd2976ab4fac4d8e1575975531644ecc62bc1d) 64 | - clarify getNodeKey docs [PR #151](https://github.com/patrick-steele-idem/morphdom/pull/151) 65 | 66 | ## 2.5.3 67 | 68 | - Minor: update deps [PR #145](https://github.com/patrick-steele-idem/morphdom/pull/145) 69 | - Minor: Minor comments and very very minor refactors [PR #143](https://github.com/patrick-steele-idem/morphdom/pull/143) 70 | 71 | ## 2.5.2 72 | 73 | - New dist for 2.5.1. My bad! 74 | 75 | ## 2.5.1 76 | 77 | - Bugfix: Fix bug where wrong select option would get selected. [PR #117](https://github.com/patrick-steele-idem/morphdom/pull/117) 78 | 79 | ## 2.5.0 80 | 81 | - Enhancement: Publish es6 format as morphdom-esm.js [PR #141](https://github.com/patrick-steele-idem/morphdom/pull/141) 82 | - Enhancement: Start removing old browser support code paths [PR #140](https://github.com/patrick-steele-idem/morphdom/pull/140) 83 | 84 | ## 2.4.0 85 | 86 | - Enhancement: Rollup 1.0 [PR #139](https://github.com/patrick-steele-idem/morphdom/pull/139) 87 | - Enhancement: Add Typescript declaration file [PR #138](https://github.com/patrick-steele-idem/morphdom/pull/138) 88 | 89 | ## 2.3.x 90 | 91 | ### 2.3.1 92 | 93 | - Bug: Fixed losing cursor position in Edge ([PR #100](https://github.com/patrick-steele-idem/morphdom/pull/100) by [@zastavnitskiy](https://github.com/zastavnitskiy)) 94 | 95 | ### 2.3.0 96 | 97 | - Changes to improve code maintainability. Single file is now split out into multiple modules and [rollup](https://github.com/rollup/rollup) is used to build the distribution files. 98 | 99 | ## 2.2.x 100 | 101 | ### 2.2.2 102 | 103 | - Changes to ensure that `selectedIndex` is updated correctly in all browsers ([PR #94](https://github.com/patrick-steele-idem/morphdom/pull/94) by [@aknuds1](https://github.com/aknuds1)) 104 | 105 | ### 2.2.1 106 | 107 | - IE-specific bug: fix ` -------------------------------------------------------------------------------- /test/fixtures/autotest/textarea/to.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/autotest/todomvc/from.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 9 |
10 | 11 | 12 |
    13 |
  • 14 |
    15 | 16 | 17 | 18 |
    19 | 20 |
  • 21 |
  • 22 |
    23 | 24 | 25 | 26 |
    27 | 28 |
  • 29 |
  • 30 |
    31 | 32 | 33 | 34 |
    35 | 36 |
  • 37 |
  • 38 |
    39 | 40 | 41 | 42 |
    43 | 44 |
  • 45 |
  • 46 |
    47 | 48 | 49 | 50 |
    51 | 52 |
  • 53 |
  • 54 |
    55 | 56 | 57 | 58 |
    59 | 60 |
  • 61 |
62 |
63 | 73 |
74 |
-------------------------------------------------------------------------------- /test/fixtures/autotest/todomvc/to.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 9 |
10 | 11 | 12 |
    13 |
  • 14 |
    15 | 16 | 17 | 18 |
    19 | 20 |
  • 21 |
  • 22 |
    23 | 24 | 25 | 26 |
    27 | 28 |
  • 29 |
  • 30 |
    31 | 32 | 33 | 34 |
    35 | 36 |
  • 37 |
  • 38 |
    39 | 40 | 41 | 42 |
    43 | 44 |
  • 45 |
  • 46 |
    47 | 48 | 49 | 50 |
    51 | 52 |
  • 53 |
  • 54 |
    55 | 56 | 57 | 58 |
    59 | 60 |
  • 61 |
  • 62 |
    63 | 64 | 65 | 66 |
    67 | 68 |
  • 69 |
70 |
71 | 81 |
82 |
-------------------------------------------------------------------------------- /test/fixtures/autotest/todomvc2/from.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/autotest/todomvc2/to.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/autotest/two/from.html: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /test/fixtures/autotest/two/to.html: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /test/fixtures/change-types/from.html: -------------------------------------------------------------------------------- 1 | italics -------------------------------------------------------------------------------- /test/fixtures/change-types/to.html: -------------------------------------------------------------------------------- 1 | bold -------------------------------------------------------------------------------- /test/fixtures/reverse-ids/from.html: -------------------------------------------------------------------------------- 1 |
w1
w2
-------------------------------------------------------------------------------- /test/fixtures/reverse-ids/to.html: -------------------------------------------------------------------------------- 1 |
w2
w1
-------------------------------------------------------------------------------- /test/mocha-headless/.gitignore: -------------------------------------------------------------------------------- 1 | /generated -------------------------------------------------------------------------------- /test/mocha-headless/browser.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | "mocha/mocha.js", 4 | "mocha/mocha.css", 5 | "require-run: ./mocha-browser-setup", 6 | "require-run: ../browser/test.js", 7 | "require-run: ../browser/benchmark.js", 8 | "./style.css" 9 | ] 10 | } -------------------------------------------------------------------------------- /test/mocha-headless/mocha-browser-setup.js: -------------------------------------------------------------------------------- 1 | window.mocha.ui('bdd'); 2 | window.mocha.reporter('html'); -------------------------------------------------------------------------------- /test/mocha-headless/run.js: -------------------------------------------------------------------------------- 1 | require('marko/node-require').install(); 2 | 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | 6 | process.chdir(path.join(__dirname, '../')); 7 | 8 | var spawn = require('child_process').spawn; 9 | 10 | require('marko/hot-reload').enable(); 11 | require('marko/compiler').defaultOptions.preserveWhitespace = true; 12 | var lasso = require('lasso'); 13 | 14 | var watch = process.env.hasOwnProperty('WATCH'); 15 | 16 | var outputDir = path.join(__dirname, 'generated'); 17 | var cacheDir = path.join(__dirname, '../.cache'); 18 | var rootDir = path.join(__dirname, '../../'); 19 | var fixturesDir = path.join(__dirname, '../fixtures'); 20 | var autotestDir = path.join(fixturesDir, 'autotest'); 21 | 22 | try { 23 | fs.mkdirSync(outputDir); 24 | } catch(e) { 25 | // Ignore the error if the directory already exists 26 | } 27 | 28 | require('lasso').configure({ 29 | outputDir: path.join(outputDir, 'static'), 30 | plugins: [ 31 | 'lasso-marko' 32 | ], 33 | urlPrefix: './static', 34 | fingerprintsEnabled: false, 35 | bundlingEnabled: false 36 | }); 37 | 38 | var running = false; 39 | var fileModified = false; 40 | 41 | var testConfig = { 42 | runBenchmarks: false, 43 | runTests: false, 44 | }; 45 | 46 | for (var i=2; i 2 | 3 | 4 | 5 | 6 | 7 | Morphdom Tests 8 | 9 | 10 | 11 |
12 |
13 | 14 |
15 |
16 | 17 |
18 |
19 | 20 | 21 |
22 | 23 |
24 |
25 |
26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | --------------------------------------------------------------------------------