jquery-morphdom 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c1973a24eefe4e78029ba67be617ecf143e9ea63
4
+ data.tar.gz: 164889da9bbfb57269757816699d43f36c5fe3c2
5
+ SHA512:
6
+ metadata.gz: b375b02168f24c160d8cf6ea27e476aeefdad78b1e44cba9ed4918fb65c314d2ec24388fc840f835ab8a6fa183779f7550a23dbfb2ef0b1998f4ebfef85fb699
7
+ data.tar.gz: dcbfb30637a5506634816bcaf8d81c7550eebed9184bf514f79ce03a68872c176dc18bffd78b0ac9bb79e4768da0c84a9303fb052d768129def174562dfa5315
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.3
4
+ before_install: gem install bundler -v 1.11.2
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at johannes@softwareseni.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jquery-morphdom.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Johannes Dwi Cahyo
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # Jquery::Morphdom
2
+
3
+ Simple gem to integrate Jquery-Morphdom library to Rails assets pipeline.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'jquery-morphdom'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install jquery-morphdom
20
+
21
+ ## Usage
22
+
23
+ Include "jquery.morphdom" in to your application.js after jquery and jquery_ujs.
24
+ ```javascript
25
+ //= require jquery.morphdom
26
+ ```
27
+ See jquery-morphdom gem usage in this [repo](https://github.com/james2doyle/jquery-morphdom).
28
+
29
+ ## Development
30
+
31
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
32
+
33
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
34
+
35
+ ## Contributing
36
+
37
+ Bug reports and pull requests are welcome on GitHub at https://github.com/johannesdwicahyo/jquery-morphdom. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
38
+
39
+
40
+ ## License
41
+
42
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
43
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "jquery/morphdom"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jquery/morphdom/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jquery-morphdom"
8
+ spec.version = Jquery::Morphdom::VERSION
9
+ spec.authors = ["Johannes Dwi Cahyo"]
10
+ spec.email = ["johannesdwicahyo@gmail.com"]
11
+
12
+ spec.summary = %q{Include jquery-morphdom to rails asset pipeline}
13
+ spec.description = %q{Include jquery-morphdom to rails asset pipeline}
14
+ spec.homepage = "https://www.github.com/johannesdwicahyo/jquery-morphdom"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.11"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rspec", "~> 3.0"
25
+ end
@@ -0,0 +1,9 @@
1
+ require "jquery/morphdom/version"
2
+
3
+ module Jquery
4
+ module Morphdom
5
+ module Rails
6
+ require 'jquery/morphdom/engine'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ module Jquery
2
+ module Morphdom
3
+ module Rails
4
+ class Engine < ::Rails::Engine
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ module Jquery
2
+ module Morphdom
3
+ VERSION = "0.1.1"
4
+ end
5
+ end
@@ -0,0 +1,611 @@
1
+ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2
+ /*!
3
+ * jquery.morphdom.js - A thin jQuery wrapped around patrick-steele-idem/morphdom
4
+ * @version v1.0.0
5
+ * @link https://github.com/james2doyle/jquery.morphdom.js
6
+ * @license MIT
7
+ * @copyright (c) 2016
8
+ */
9
+
10
+ (function($) {
11
+
12
+ var morphdom = require('morphdom');
13
+
14
+ $.fn.morphdom = function(node, options) {
15
+
16
+ if (!this.length) { return this; }
17
+
18
+ // default options
19
+ $.fn.morphdom.defaults = {};
20
+
21
+ var opts = $.extend(true, {}, $.fn.morphdom.defaults, options);
22
+
23
+ if (typeof(node) === 'object') {
24
+ node = node[0];
25
+ }
26
+
27
+ var results = $(morphdom(this[0], node, opts));
28
+
29
+ if (typeof(options) === 'function') {
30
+ options(results);
31
+ }
32
+
33
+ return results;
34
+ };
35
+
36
+ })(jQuery);
37
+
38
+ },{"morphdom":2}],2:[function(require,module,exports){
39
+ // Create a range object for efficently rendering strings to elements.
40
+ var range;
41
+
42
+ var testEl = (typeof document !== 'undefined') ?
43
+ document.body || document.createElement('div') :
44
+ {};
45
+
46
+ var XHTML = 'http://www.w3.org/1999/xhtml';
47
+ var ELEMENT_NODE = 1;
48
+ var TEXT_NODE = 3;
49
+
50
+ // Fixes <https://github.com/patrick-steele-idem/morphdom/issues/32>
51
+ // (IE7+ support) <=IE7 does not support el.hasAttribute(name)
52
+ var hasAttributeNS;
53
+
54
+ if (testEl.hasAttributeNS) {
55
+ hasAttributeNS = function(el, namespaceURI, name) {
56
+ return el.hasAttributeNS(namespaceURI, name);
57
+ };
58
+ } else if (testEl.hasAttribute) {
59
+ hasAttributeNS = function(el, namespaceURI, name) {
60
+ return el.hasAttribute(name);
61
+ };
62
+ } else {
63
+ hasAttributeNS = function(el, namespaceURI, name) {
64
+ return !!el.getAttributeNode(name);
65
+ };
66
+ }
67
+
68
+ function empty(o) {
69
+ for (var k in o) {
70
+ if (o.hasOwnProperty(k)) {
71
+ return false;
72
+ }
73
+ }
74
+ return true;
75
+ }
76
+
77
+ function toElement(str) {
78
+ if (!range && document.createRange) {
79
+ range = document.createRange();
80
+ range.selectNode(document.body);
81
+ }
82
+
83
+ var fragment;
84
+ if (range && range.createContextualFragment) {
85
+ fragment = range.createContextualFragment(str);
86
+ } else {
87
+ fragment = document.createElement('body');
88
+ fragment.innerHTML = str;
89
+ }
90
+ return fragment.childNodes[0];
91
+ }
92
+
93
+ var specialElHandlers = {
94
+ /**
95
+ * Needed for IE. Apparently IE doesn't think that "selected" is an
96
+ * attribute when reading over the attributes using selectEl.attributes
97
+ */
98
+ OPTION: function(fromEl, toEl) {
99
+ fromEl.selected = toEl.selected;
100
+ if (fromEl.selected) {
101
+ fromEl.setAttribute('selected', '');
102
+ } else {
103
+ fromEl.removeAttribute('selected', '');
104
+ }
105
+ },
106
+ /**
107
+ * The "value" attribute is special for the <input> element since it sets
108
+ * the initial value. Changing the "value" attribute without changing the
109
+ * "value" property will have no effect since it is only used to the set the
110
+ * initial value. Similar for the "checked" attribute, and "disabled".
111
+ */
112
+ INPUT: function(fromEl, toEl) {
113
+ fromEl.checked = toEl.checked;
114
+ if (fromEl.checked) {
115
+ fromEl.setAttribute('checked', '');
116
+ } else {
117
+ fromEl.removeAttribute('checked');
118
+ }
119
+
120
+ if (fromEl.value !== toEl.value) {
121
+ fromEl.value = toEl.value;
122
+ }
123
+
124
+ if (!hasAttributeNS(toEl, null, 'value')) {
125
+ fromEl.removeAttribute('value');
126
+ }
127
+
128
+ fromEl.disabled = toEl.disabled;
129
+ if (fromEl.disabled) {
130
+ fromEl.setAttribute('disabled', '');
131
+ } else {
132
+ fromEl.removeAttribute('disabled');
133
+ }
134
+ },
135
+
136
+ TEXTAREA: function(fromEl, toEl) {
137
+ var newValue = toEl.value;
138
+ if (fromEl.value !== newValue) {
139
+ fromEl.value = newValue;
140
+ }
141
+
142
+ if (fromEl.firstChild) {
143
+ fromEl.firstChild.nodeValue = newValue;
144
+ }
145
+ }
146
+ };
147
+
148
+ function noop() {}
149
+
150
+ /**
151
+ * Returns true if two node's names and namespace URIs are the same.
152
+ *
153
+ * @param {Element} a
154
+ * @param {Element} b
155
+ * @return {boolean}
156
+ */
157
+ var compareNodeNames = function(a, b) {
158
+ return a.nodeName === b.nodeName &&
159
+ a.namespaceURI === b.namespaceURI;
160
+ };
161
+
162
+ /**
163
+ * Create an element, optionally with a known namespace URI.
164
+ *
165
+ * @param {string} name the element name, e.g. 'div' or 'svg'
166
+ * @param {string} [namespaceURI] the element's namespace URI, i.e. the value of
167
+ * its `xmlns` attribute or its inferred namespace.
168
+ *
169
+ * @return {Element}
170
+ */
171
+ function createElementNS(name, namespaceURI) {
172
+ return !namespaceURI || namespaceURI === XHTML ?
173
+ document.createElement(name) :
174
+ document.createElementNS(namespaceURI, name);
175
+ }
176
+
177
+ /**
178
+ * Loop over all of the attributes on the target node and make sure the original
179
+ * DOM node has the same attributes. If an attribute found on the original node
180
+ * is not on the new node then remove it from the original node.
181
+ *
182
+ * @param {Element} fromNode
183
+ * @param {Element} toNode
184
+ */
185
+ function morphAttrs(fromNode, toNode) {
186
+ var attrs = toNode.attributes;
187
+ var i;
188
+ var attr;
189
+ var attrName;
190
+ var attrNamespaceURI;
191
+ var attrValue;
192
+ var fromValue;
193
+
194
+ for (i = attrs.length - 1; i >= 0; i--) {
195
+ attr = attrs[i];
196
+ attrName = attr.name;
197
+ attrValue = attr.value;
198
+ attrNamespaceURI = attr.namespaceURI;
199
+
200
+ if (attrNamespaceURI) {
201
+ attrName = attr.localName || attrName;
202
+ fromValue = fromNode.getAttributeNS(attrNamespaceURI, attrName);
203
+ } else {
204
+ fromValue = fromNode.getAttribute(attrName);
205
+ }
206
+
207
+ if (fromValue !== attrValue) {
208
+ if (attrNamespaceURI) {
209
+ fromNode.setAttributeNS(attrNamespaceURI, attrName, attrValue);
210
+ } else {
211
+ fromNode.setAttribute(attrName, attrValue);
212
+ }
213
+ }
214
+ }
215
+
216
+ // Remove any extra attributes found on the original DOM element that
217
+ // weren't found on the target element.
218
+ attrs = fromNode.attributes;
219
+
220
+ for (i = attrs.length - 1; i >= 0; i--) {
221
+ attr = attrs[i];
222
+ if (attr.specified !== false) {
223
+ attrName = attr.name;
224
+ attrNamespaceURI = attr.namespaceURI;
225
+
226
+ if (!hasAttributeNS(toNode, attrNamespaceURI, attrNamespaceURI ? attrName = attr.localName || attrName : attrName)) {
227
+ fromNode.removeAttributeNode(attr);
228
+ }
229
+ }
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Copies the children of one DOM element to another DOM element
235
+ */
236
+ function moveChildren(fromEl, toEl) {
237
+ var curChild = fromEl.firstChild;
238
+ while (curChild) {
239
+ var nextChild = curChild.nextSibling;
240
+ toEl.appendChild(curChild);
241
+ curChild = nextChild;
242
+ }
243
+ return toEl;
244
+ }
245
+
246
+ function defaultGetNodeKey(node) {
247
+ return node.id;
248
+ }
249
+
250
+ function morphdom(fromNode, toNode, options) {
251
+ if (!options) {
252
+ options = {};
253
+ }
254
+
255
+ if (typeof toNode === 'string') {
256
+ if (fromNode.nodeName === '#document' || fromNode.nodeName === 'HTML') {
257
+ var toNodeHtml = toNode;
258
+ toNode = document.createElement('html');
259
+ toNode.innerHTML = toNodeHtml;
260
+ } else {
261
+ toNode = toElement(toNode);
262
+ }
263
+ }
264
+
265
+ // XXX optimization: if the nodes are equal, don't morph them
266
+ /*
267
+ if (fromNode.isEqualNode(toNode)) {
268
+ return fromNode;
269
+ }
270
+ */
271
+
272
+ var savedEls = {}; // Used to save off DOM elements with IDs
273
+ var unmatchedEls = {};
274
+ var getNodeKey = options.getNodeKey || defaultGetNodeKey;
275
+ var onBeforeNodeAdded = options.onBeforeNodeAdded || noop;
276
+ var onNodeAdded = options.onNodeAdded || noop;
277
+ var onBeforeElUpdated = options.onBeforeElUpdated || options.onBeforeMorphEl || noop;
278
+ var onElUpdated = options.onElUpdated || noop;
279
+ var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop;
280
+ var onNodeDiscarded = options.onNodeDiscarded || noop;
281
+ var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || options.onBeforeMorphElChildren || noop;
282
+ var childrenOnly = options.childrenOnly === true;
283
+ var movedEls = [];
284
+
285
+ function removeNodeHelper(node, nestedInSavedEl) {
286
+ var id = getNodeKey(node);
287
+ // If the node has an ID then save it off since we will want
288
+ // to reuse it in case the target DOM tree has a DOM element
289
+ // with the same ID
290
+ if (id) {
291
+ savedEls[id] = node;
292
+ } else if (!nestedInSavedEl) {
293
+ // If we are not nested in a saved element then we know that this node has been
294
+ // completely discarded and will not exist in the final DOM.
295
+ onNodeDiscarded(node);
296
+ }
297
+
298
+ if (node.nodeType === ELEMENT_NODE) {
299
+ var curChild = node.firstChild;
300
+ while (curChild) {
301
+ removeNodeHelper(curChild, nestedInSavedEl || id);
302
+ curChild = curChild.nextSibling;
303
+ }
304
+ }
305
+ }
306
+
307
+ function walkDiscardedChildNodes(node) {
308
+ if (node.nodeType === ELEMENT_NODE) {
309
+ var curChild = node.firstChild;
310
+ while (curChild) {
311
+
312
+
313
+ if (!getNodeKey(curChild)) {
314
+ // We only want to handle nodes that don't have an ID to avoid double
315
+ // walking the same saved element.
316
+
317
+ onNodeDiscarded(curChild);
318
+
319
+ // Walk recursively
320
+ walkDiscardedChildNodes(curChild);
321
+ }
322
+
323
+ curChild = curChild.nextSibling;
324
+ }
325
+ }
326
+ }
327
+
328
+ function removeNode(node, parentNode, alreadyVisited) {
329
+ if (onBeforeNodeDiscarded(node) === false) {
330
+ return;
331
+ }
332
+
333
+ parentNode.removeChild(node);
334
+ if (alreadyVisited) {
335
+ if (!getNodeKey(node)) {
336
+ onNodeDiscarded(node);
337
+ walkDiscardedChildNodes(node);
338
+ }
339
+ } else {
340
+ removeNodeHelper(node);
341
+ }
342
+ }
343
+
344
+ function morphEl(fromEl, toEl, alreadyVisited, childrenOnly) {
345
+ var toElKey = getNodeKey(toEl);
346
+ if (toElKey) {
347
+ // If an element with an ID is being morphed then it is will be in the final
348
+ // DOM so clear it out of the saved elements collection
349
+ delete savedEls[toElKey];
350
+ }
351
+
352
+ if (!childrenOnly) {
353
+ if (onBeforeElUpdated(fromEl, toEl) === false) {
354
+ return;
355
+ }
356
+
357
+ morphAttrs(fromEl, toEl);
358
+ onElUpdated(fromEl);
359
+
360
+ if (onBeforeElChildrenUpdated(fromEl, toEl) === false) {
361
+ return;
362
+ }
363
+ }
364
+
365
+ if (fromEl.nodeName !== 'TEXTAREA') {
366
+ var curToNodeChild = toEl.firstChild;
367
+ var curFromNodeChild = fromEl.firstChild;
368
+ var curToNodeId;
369
+
370
+ var fromNextSibling;
371
+ var toNextSibling;
372
+ var savedEl;
373
+ var unmatchedEl;
374
+
375
+ outer: while (curToNodeChild) {
376
+ toNextSibling = curToNodeChild.nextSibling;
377
+ curToNodeId = getNodeKey(curToNodeChild);
378
+
379
+ while (curFromNodeChild) {
380
+ var curFromNodeId = getNodeKey(curFromNodeChild);
381
+ fromNextSibling = curFromNodeChild.nextSibling;
382
+
383
+ if (!alreadyVisited) {
384
+ if (curFromNodeId && (unmatchedEl = unmatchedEls[curFromNodeId])) {
385
+ unmatchedEl.parentNode.replaceChild(curFromNodeChild, unmatchedEl);
386
+ morphEl(curFromNodeChild, unmatchedEl, alreadyVisited);
387
+ curFromNodeChild = fromNextSibling;
388
+ continue;
389
+ }
390
+ }
391
+
392
+ var curFromNodeType = curFromNodeChild.nodeType;
393
+
394
+ if (curFromNodeType === curToNodeChild.nodeType) {
395
+ var isCompatible = false;
396
+
397
+ // Both nodes being compared are Element nodes
398
+ if (curFromNodeType === ELEMENT_NODE) {
399
+ if (compareNodeNames(curFromNodeChild, curToNodeChild)) {
400
+ // We have compatible DOM elements
401
+ if (curFromNodeId || curToNodeId) {
402
+ // If either DOM element has an ID then we
403
+ // handle those differently since we want to
404
+ // match up by ID
405
+ if (curToNodeId === curFromNodeId) {
406
+ isCompatible = true;
407
+ }
408
+ } else {
409
+ isCompatible = true;
410
+ }
411
+ }
412
+
413
+ if (isCompatible) {
414
+ // We found compatible DOM elements so transform
415
+ // the current "from" node to match the current
416
+ // target DOM node.
417
+ morphEl(curFromNodeChild, curToNodeChild, alreadyVisited);
418
+ }
419
+ // Both nodes being compared are Text nodes
420
+ } else if (curFromNodeType === TEXT_NODE) {
421
+ isCompatible = true;
422
+ // Simply update nodeValue on the original node to
423
+ // change the text value
424
+ curFromNodeChild.nodeValue = curToNodeChild.nodeValue;
425
+ }
426
+
427
+ if (isCompatible) {
428
+ curToNodeChild = toNextSibling;
429
+ curFromNodeChild = fromNextSibling;
430
+ continue outer;
431
+ }
432
+ }
433
+
434
+ // No compatible match so remove the old node from the DOM
435
+ // and continue trying to find a match in the original DOM
436
+ removeNode(curFromNodeChild, fromEl, alreadyVisited);
437
+ curFromNodeChild = fromNextSibling;
438
+ }
439
+
440
+ if (curToNodeId) {
441
+ if ((savedEl = savedEls[curToNodeId])) {
442
+ morphEl(savedEl, curToNodeChild, true);
443
+ // We want to append the saved element instead
444
+ curToNodeChild = savedEl;
445
+ } else {
446
+ // The current DOM element in the target tree has an ID
447
+ // but we did not find a match in any of the
448
+ // corresponding siblings. We just put the target
449
+ // element in the old DOM tree but if we later find an
450
+ // element in the old DOM tree that has a matching ID
451
+ // then we will replace the target element with the
452
+ // corresponding old element and morph the old element
453
+ unmatchedEls[curToNodeId] = curToNodeChild;
454
+ }
455
+ }
456
+
457
+ // If we got this far then we did not find a candidate match for
458
+ // our "to node" and we exhausted all of the children "from"
459
+ // nodes. Therefore, we will just append the current "to node"
460
+ // to the end
461
+ if (onBeforeNodeAdded(curToNodeChild) !== false) {
462
+ fromEl.appendChild(curToNodeChild);
463
+ onNodeAdded(curToNodeChild);
464
+ }
465
+
466
+ if (curToNodeChild.nodeType === ELEMENT_NODE &&
467
+ (curToNodeId || curToNodeChild.firstChild)) {
468
+ // The element that was just added to the original DOM may
469
+ // have some nested elements with a key/ID that needs to be
470
+ // matched up with other elements. We'll add the element to
471
+ // a list so that we can later process the nested elements
472
+ // if there are any unmatched keyed elements that were
473
+ // discarded
474
+ movedEls.push(curToNodeChild);
475
+ }
476
+
477
+ curToNodeChild = toNextSibling;
478
+ curFromNodeChild = fromNextSibling;
479
+ }
480
+
481
+ // We have processed all of the "to nodes". If curFromNodeChild is
482
+ // non-null then we still have some from nodes left over that need
483
+ // to be removed
484
+ while (curFromNodeChild) {
485
+ fromNextSibling = curFromNodeChild.nextSibling;
486
+ removeNode(curFromNodeChild, fromEl, alreadyVisited);
487
+ curFromNodeChild = fromNextSibling;
488
+ }
489
+ }
490
+
491
+ var specialElHandler = specialElHandlers[fromEl.nodeName];
492
+ if (specialElHandler) {
493
+ specialElHandler(fromEl, toEl);
494
+ }
495
+ } // END: morphEl(...)
496
+
497
+ var morphedNode = fromNode;
498
+ var morphedNodeType = morphedNode.nodeType;
499
+ var toNodeType = toNode.nodeType;
500
+
501
+ if (!childrenOnly) {
502
+ // Handle the case where we are given two DOM nodes that are not
503
+ // compatible (e.g. <div> --> <span> or <div> --> TEXT)
504
+ if (morphedNodeType === ELEMENT_NODE) {
505
+ if (toNodeType === ELEMENT_NODE) {
506
+ if (!compareNodeNames(fromNode, toNode)) {
507
+ onNodeDiscarded(fromNode);
508
+ morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI));
509
+ }
510
+ } else {
511
+ // Going from an element node to a text node
512
+ morphedNode = toNode;
513
+ }
514
+ } else if (morphedNodeType === TEXT_NODE) { // Text node
515
+ if (toNodeType === TEXT_NODE) {
516
+ morphedNode.nodeValue = toNode.nodeValue;
517
+ return morphedNode;
518
+ } else {
519
+ // Text node to something else
520
+ morphedNode = toNode;
521
+ }
522
+ }
523
+ }
524
+
525
+ if (morphedNode === toNode) {
526
+ // The "to node" was not compatible with the "from node" so we had to
527
+ // toss out the "from node" and use the "to node"
528
+ onNodeDiscarded(fromNode);
529
+ } else {
530
+ morphEl(morphedNode, toNode, false, childrenOnly);
531
+
532
+ /**
533
+ * What we will do here is walk the tree for the DOM element that was
534
+ * moved from the target DOM tree to the original DOM tree and we will
535
+ * look for keyed elements that could be matched to keyed elements that
536
+ * were earlier discarded. If we find a match then we will move the
537
+ * saved element into the final DOM tree.
538
+ */
539
+ var handleMovedEl = function(el) {
540
+ var curChild = el.firstChild;
541
+ while (curChild) {
542
+ var nextSibling = curChild.nextSibling;
543
+
544
+ var key = getNodeKey(curChild);
545
+ if (key) {
546
+ var savedEl = savedEls[key];
547
+ if (savedEl && compareNodeNames(curChild, savedEl)) {
548
+ curChild.parentNode.replaceChild(savedEl, curChild);
549
+ // true: already visited the saved el tree
550
+ morphEl(savedEl, curChild, true);
551
+ curChild = nextSibling;
552
+ if (empty(savedEls)) {
553
+ return false;
554
+ }
555
+ continue;
556
+ }
557
+ }
558
+
559
+ if (curChild.nodeType === ELEMENT_NODE) {
560
+ handleMovedEl(curChild);
561
+ }
562
+
563
+ curChild = nextSibling;
564
+ }
565
+ };
566
+
567
+ // The loop below is used to possibly match up any discarded
568
+ // elements in the original DOM tree with elemenets from the
569
+ // target tree that were moved over without visiting their
570
+ // children
571
+ if (!empty(savedEls)) {
572
+ handleMovedElsLoop:
573
+ while (movedEls.length) {
574
+ var movedElsTemp = movedEls;
575
+ movedEls = [];
576
+ for (var i=0; i<movedElsTemp.length; i++) {
577
+ if (handleMovedEl(movedElsTemp[i]) === false) {
578
+ // There are no more unmatched elements so completely end
579
+ // the loop
580
+ break handleMovedElsLoop;
581
+ }
582
+ }
583
+ }
584
+ }
585
+
586
+ // Fire the "onNodeDiscarded" event for any saved elements
587
+ // that never found a new home in the morphed DOM
588
+ for (var savedElId in savedEls) {
589
+ if (savedEls.hasOwnProperty(savedElId)) {
590
+ var savedEl = savedEls[savedElId];
591
+ onNodeDiscarded(savedEl);
592
+ walkDiscardedChildNodes(savedEl);
593
+ }
594
+ }
595
+ }
596
+
597
+ if (!childrenOnly && morphedNode !== fromNode && fromNode.parentNode) {
598
+ // If we had to swap out the from node with a new node because the old
599
+ // node was not compatible with the target node then we need to
600
+ // replace the old DOM node in the original DOM tree. This is only
601
+ // possible if the original DOM node was part of a DOM tree which
602
+ // we know is the case if it has a parent node.
603
+ fromNode.parentNode.replaceChild(morphedNode, fromNode);
604
+ }
605
+
606
+ return morphedNode;
607
+ }
608
+
609
+ module.exports = morphdom;
610
+
611
+ },{}]},{},[1]);
@@ -0,0 +1 @@
1
+ !function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require){!function($){var morphdom=require("morphdom");$.fn.morphdom=function(node,options){if(!this.length)return this;$.fn.morphdom.defaults={};var opts=$.extend(!0,{},$.fn.morphdom.defaults,options);"object"==typeof node&&(node=node[0]);var results=$(morphdom(this[0],node,opts));return"function"==typeof options&&options(results),results}}(jQuery)},{morphdom:2}],2:[function(require,module){function empty(o){for(var k in o)if(o.hasOwnProperty(k))return!1;return!0}function toElement(str){!range&&document.createRange&&(range=document.createRange(),range.selectNode(document.body));var fragment;return range&&range.createContextualFragment?fragment=range.createContextualFragment(str):(fragment=document.createElement("body"),fragment.innerHTML=str),fragment.childNodes[0]}function noop(){}function createElementNS(name,namespaceURI){return namespaceURI&&namespaceURI!==XHTML?document.createElementNS(namespaceURI,name):document.createElement(name)}function morphAttrs(fromNode,toNode){var i,attr,attrName,attrNamespaceURI,attrValue,fromValue,attrs=toNode.attributes;for(i=attrs.length-1;i>=0;i--)attr=attrs[i],attrName=attr.name,attrValue=attr.value,attrNamespaceURI=attr.namespaceURI,attrNamespaceURI?(attrName=attr.localName||attrName,fromValue=fromNode.getAttributeNS(attrNamespaceURI,attrName)):fromValue=fromNode.getAttribute(attrName),fromValue!==attrValue&&(attrNamespaceURI?fromNode.setAttributeNS(attrNamespaceURI,attrName,attrValue):fromNode.setAttribute(attrName,attrValue));for(attrs=fromNode.attributes,i=attrs.length-1;i>=0;i--)attr=attrs[i],attr.specified!==!1&&(attrName=attr.name,attrNamespaceURI=attr.namespaceURI,hasAttributeNS(toNode,attrNamespaceURI,attrNamespaceURI?attrName=attr.localName||attrName:attrName)||fromNode.removeAttributeNode(attr))}function moveChildren(fromEl,toEl){for(var curChild=fromEl.firstChild;curChild;){var nextChild=curChild.nextSibling;toEl.appendChild(curChild),curChild=nextChild}return toEl}function defaultGetNodeKey(node){return node.id}function morphdom(fromNode,toNode,options){function removeNodeHelper(node,nestedInSavedEl){var id=getNodeKey(node);if(id?savedEls[id]=node:nestedInSavedEl||onNodeDiscarded(node),node.nodeType===ELEMENT_NODE)for(var curChild=node.firstChild;curChild;)removeNodeHelper(curChild,nestedInSavedEl||id),curChild=curChild.nextSibling}function walkDiscardedChildNodes(node){if(node.nodeType===ELEMENT_NODE)for(var curChild=node.firstChild;curChild;)getNodeKey(curChild)||(onNodeDiscarded(curChild),walkDiscardedChildNodes(curChild)),curChild=curChild.nextSibling}function removeNode(node,parentNode,alreadyVisited){onBeforeNodeDiscarded(node)!==!1&&(parentNode.removeChild(node),alreadyVisited?getNodeKey(node)||(onNodeDiscarded(node),walkDiscardedChildNodes(node)):removeNodeHelper(node))}function morphEl(fromEl,toEl,alreadyVisited,childrenOnly){var toElKey=getNodeKey(toEl);if(toElKey&&delete savedEls[toElKey],!childrenOnly){if(onBeforeElUpdated(fromEl,toEl)===!1)return;if(morphAttrs(fromEl,toEl),onElUpdated(fromEl),onBeforeElChildrenUpdated(fromEl,toEl)===!1)return}if("TEXTAREA"!==fromEl.nodeName){var curToNodeId,fromNextSibling,toNextSibling,savedEl,unmatchedEl,curToNodeChild=toEl.firstChild,curFromNodeChild=fromEl.firstChild;outer:for(;curToNodeChild;){for(toNextSibling=curToNodeChild.nextSibling,curToNodeId=getNodeKey(curToNodeChild);curFromNodeChild;){var curFromNodeId=getNodeKey(curFromNodeChild);if(fromNextSibling=curFromNodeChild.nextSibling,!alreadyVisited&&curFromNodeId&&(unmatchedEl=unmatchedEls[curFromNodeId]))unmatchedEl.parentNode.replaceChild(curFromNodeChild,unmatchedEl),morphEl(curFromNodeChild,unmatchedEl,alreadyVisited),curFromNodeChild=fromNextSibling;else{var curFromNodeType=curFromNodeChild.nodeType;if(curFromNodeType===curToNodeChild.nodeType){var isCompatible=!1;if(curFromNodeType===ELEMENT_NODE?(compareNodeNames(curFromNodeChild,curToNodeChild)&&(curFromNodeId||curToNodeId?curToNodeId===curFromNodeId&&(isCompatible=!0):isCompatible=!0),isCompatible&&morphEl(curFromNodeChild,curToNodeChild,alreadyVisited)):curFromNodeType===TEXT_NODE&&(isCompatible=!0,curFromNodeChild.nodeValue=curToNodeChild.nodeValue),isCompatible){curToNodeChild=toNextSibling,curFromNodeChild=fromNextSibling;continue outer}}removeNode(curFromNodeChild,fromEl,alreadyVisited),curFromNodeChild=fromNextSibling}}curToNodeId&&((savedEl=savedEls[curToNodeId])?(morphEl(savedEl,curToNodeChild,!0),curToNodeChild=savedEl):unmatchedEls[curToNodeId]=curToNodeChild),onBeforeNodeAdded(curToNodeChild)!==!1&&(fromEl.appendChild(curToNodeChild),onNodeAdded(curToNodeChild)),curToNodeChild.nodeType===ELEMENT_NODE&&(curToNodeId||curToNodeChild.firstChild)&&movedEls.push(curToNodeChild),curToNodeChild=toNextSibling,curFromNodeChild=fromNextSibling}for(;curFromNodeChild;)fromNextSibling=curFromNodeChild.nextSibling,removeNode(curFromNodeChild,fromEl,alreadyVisited),curFromNodeChild=fromNextSibling}var specialElHandler=specialElHandlers[fromEl.nodeName];specialElHandler&&specialElHandler(fromEl,toEl)}if(options||(options={}),"string"==typeof toNode)if("#document"===fromNode.nodeName||"HTML"===fromNode.nodeName){var toNodeHtml=toNode;toNode=document.createElement("html"),toNode.innerHTML=toNodeHtml}else toNode=toElement(toNode);var savedEls={},unmatchedEls={},getNodeKey=options.getNodeKey||defaultGetNodeKey,onBeforeNodeAdded=options.onBeforeNodeAdded||noop,onNodeAdded=options.onNodeAdded||noop,onBeforeElUpdated=options.onBeforeElUpdated||options.onBeforeMorphEl||noop,onElUpdated=options.onElUpdated||noop,onBeforeNodeDiscarded=options.onBeforeNodeDiscarded||noop,onNodeDiscarded=options.onNodeDiscarded||noop,onBeforeElChildrenUpdated=options.onBeforeElChildrenUpdated||options.onBeforeMorphElChildren||noop,childrenOnly=options.childrenOnly===!0,movedEls=[],morphedNode=fromNode,morphedNodeType=morphedNode.nodeType,toNodeType=toNode.nodeType;if(!childrenOnly)if(morphedNodeType===ELEMENT_NODE)toNodeType===ELEMENT_NODE?compareNodeNames(fromNode,toNode)||(onNodeDiscarded(fromNode),morphedNode=moveChildren(fromNode,createElementNS(toNode.nodeName,toNode.namespaceURI))):morphedNode=toNode;else if(morphedNodeType===TEXT_NODE){if(toNodeType===TEXT_NODE)return morphedNode.nodeValue=toNode.nodeValue,morphedNode;morphedNode=toNode}if(morphedNode===toNode)onNodeDiscarded(fromNode);else{morphEl(morphedNode,toNode,!1,childrenOnly);var handleMovedEl=function(el){for(var curChild=el.firstChild;curChild;){var nextSibling=curChild.nextSibling,key=getNodeKey(curChild);if(key){var savedEl=savedEls[key];if(savedEl&&compareNodeNames(curChild,savedEl)){if(curChild.parentNode.replaceChild(savedEl,curChild),morphEl(savedEl,curChild,!0),curChild=nextSibling,empty(savedEls))return!1;continue}}curChild.nodeType===ELEMENT_NODE&&handleMovedEl(curChild),curChild=nextSibling}};if(!empty(savedEls))handleMovedElsLoop:for(;movedEls.length;){var movedElsTemp=movedEls;movedEls=[];for(var i=0;i<movedElsTemp.length;i++)if(handleMovedEl(movedElsTemp[i])===!1)break handleMovedElsLoop}for(var savedElId in savedEls)if(savedEls.hasOwnProperty(savedElId)){var savedEl=savedEls[savedElId];onNodeDiscarded(savedEl),walkDiscardedChildNodes(savedEl)}}return!childrenOnly&&morphedNode!==fromNode&&fromNode.parentNode&&fromNode.parentNode.replaceChild(morphedNode,fromNode),morphedNode}var range,hasAttributeNS,testEl="undefined"!=typeof document?document.body||document.createElement("div"):{},XHTML="http://www.w3.org/1999/xhtml",ELEMENT_NODE=1,TEXT_NODE=3;hasAttributeNS=testEl.hasAttributeNS?function(el,namespaceURI,name){return el.hasAttributeNS(namespaceURI,name)}:testEl.hasAttribute?function(el,namespaceURI,name){return el.hasAttribute(name)}:function(el,namespaceURI,name){return!!el.getAttributeNode(name)};var specialElHandlers={OPTION:function(fromEl,toEl){fromEl.selected=toEl.selected,fromEl.selected?fromEl.setAttribute("selected",""):fromEl.removeAttribute("selected","")},INPUT:function(fromEl,toEl){fromEl.checked=toEl.checked,fromEl.checked?fromEl.setAttribute("checked",""):fromEl.removeAttribute("checked"),fromEl.value!==toEl.value&&(fromEl.value=toEl.value),hasAttributeNS(toEl,null,"value")||fromEl.removeAttribute("value"),fromEl.disabled=toEl.disabled,fromEl.disabled?fromEl.setAttribute("disabled",""):fromEl.removeAttribute("disabled")},TEXTAREA:function(fromEl,toEl){var newValue=toEl.value;fromEl.value!==newValue&&(fromEl.value=newValue),fromEl.firstChild&&(fromEl.firstChild.nodeValue=newValue)}},compareNodeNames=function(a,b){return a.nodeName===b.nodeName&&a.namespaceURI===b.namespaceURI};module.exports=morphdom},{}]},{},[1]);
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jquery-morphdom
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Johannes Dwi Cahyo
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-08-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: Include jquery-morphdom to rails asset pipeline
56
+ email:
57
+ - johannesdwicahyo@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".travis.yml"
65
+ - CODE_OF_CONDUCT.md
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - bin/console
71
+ - bin/setup
72
+ - jquery-morphdom.gemspec
73
+ - lib/jquery/morphdom.rb
74
+ - lib/jquery/morphdom/engine.rb
75
+ - lib/jquery/morphdom/version.rb
76
+ - vendor/assets/javascripts/jquery.morphdom.js
77
+ - vendor/assets/javascripts/jquery.morphdom.min.js
78
+ homepage: https://www.github.com/johannesdwicahyo/jquery-morphdom
79
+ licenses:
80
+ - MIT
81
+ metadata: {}
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 2.4.5.1
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: Include jquery-morphdom to rails asset pipeline
102
+ test_files: []