Caleb Porzio 5 år sedan
förälder
incheckning
66ce2da45a
10 ändrade filer med 88 tillägg och 225 borttagningar
  1. 1 1
      dist/mix-manifest.json
  2. 12 209
      dist/project-x.js
  3. 1 1
      index.html
  4. 5 8
      src/index.js
  5. 2 1
      src/utils.js
  6. 5 1
      test/bind.spec.js
  7. 46 0
      test/constructor.spec.js
  8. 6 2
      test/model.spec.js
  9. 5 1
      test/on.spec.js
  10. 5 1
      test/text.spec.js

+ 1 - 1
dist/mix-manifest.json

@@ -1,4 +1,4 @@
 {
-    "/project-x.js": "/project-x.js?id=fda3c00aa0be2990236a",
+    "/project-x.js": "/project-x.js?id=956c347a4c443cc9eabd",
     "/project-x.min.js": "/project-x.min.js?id=594fb2ceb5a9311a8dfb"
 }

+ 12 - 209
dist/project-x.js

@@ -106,201 +106,6 @@ return /******/ (function(modules) { // webpackBootstrap
 module.exports = __webpack_require__(/*! regenerator-runtime */ "./node_modules/regenerator-runtime/runtime.js");
 
 
-/***/ }),
-
-/***/ "./node_modules/process/browser.js":
-/*!*****************************************!*\
-  !*** ./node_modules/process/browser.js ***!
-  \*****************************************/
-/*! no static exports found */
-/***/ (function(module, exports) {
-
-// shim for using process in browser
-var process = module.exports = {};
-
-// cached from whatever global is present so that test runners that stub it
-// don't break things.  But we need to wrap it in a try catch in case it is
-// wrapped in strict mode code which doesn't define any globals.  It's inside a
-// function because try/catches deoptimize in certain engines.
-
-var cachedSetTimeout;
-var cachedClearTimeout;
-
-function defaultSetTimout() {
-    throw new Error('setTimeout has not been defined');
-}
-function defaultClearTimeout () {
-    throw new Error('clearTimeout has not been defined');
-}
-(function () {
-    try {
-        if (typeof setTimeout === 'function') {
-            cachedSetTimeout = setTimeout;
-        } else {
-            cachedSetTimeout = defaultSetTimout;
-        }
-    } catch (e) {
-        cachedSetTimeout = defaultSetTimout;
-    }
-    try {
-        if (typeof clearTimeout === 'function') {
-            cachedClearTimeout = clearTimeout;
-        } else {
-            cachedClearTimeout = defaultClearTimeout;
-        }
-    } catch (e) {
-        cachedClearTimeout = defaultClearTimeout;
-    }
-} ())
-function runTimeout(fun) {
-    if (cachedSetTimeout === setTimeout) {
-        //normal enviroments in sane situations
-        return setTimeout(fun, 0);
-    }
-    // if setTimeout wasn't available but was latter defined
-    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
-        cachedSetTimeout = setTimeout;
-        return setTimeout(fun, 0);
-    }
-    try {
-        // when when somebody has screwed with setTimeout but no I.E. maddness
-        return cachedSetTimeout(fun, 0);
-    } catch(e){
-        try {
-            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
-            return cachedSetTimeout.call(null, fun, 0);
-        } catch(e){
-            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
-            return cachedSetTimeout.call(this, fun, 0);
-        }
-    }
-
-
-}
-function runClearTimeout(marker) {
-    if (cachedClearTimeout === clearTimeout) {
-        //normal enviroments in sane situations
-        return clearTimeout(marker);
-    }
-    // if clearTimeout wasn't available but was latter defined
-    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
-        cachedClearTimeout = clearTimeout;
-        return clearTimeout(marker);
-    }
-    try {
-        // when when somebody has screwed with setTimeout but no I.E. maddness
-        return cachedClearTimeout(marker);
-    } catch (e){
-        try {
-            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
-            return cachedClearTimeout.call(null, marker);
-        } catch (e){
-            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
-            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
-            return cachedClearTimeout.call(this, marker);
-        }
-    }
-
-
-
-}
-var queue = [];
-var draining = false;
-var currentQueue;
-var queueIndex = -1;
-
-function cleanUpNextTick() {
-    if (!draining || !currentQueue) {
-        return;
-    }
-    draining = false;
-    if (currentQueue.length) {
-        queue = currentQueue.concat(queue);
-    } else {
-        queueIndex = -1;
-    }
-    if (queue.length) {
-        drainQueue();
-    }
-}
-
-function drainQueue() {
-    if (draining) {
-        return;
-    }
-    var timeout = runTimeout(cleanUpNextTick);
-    draining = true;
-
-    var len = queue.length;
-    while(len) {
-        currentQueue = queue;
-        queue = [];
-        while (++queueIndex < len) {
-            if (currentQueue) {
-                currentQueue[queueIndex].run();
-            }
-        }
-        queueIndex = -1;
-        len = queue.length;
-    }
-    currentQueue = null;
-    draining = false;
-    runClearTimeout(timeout);
-}
-
-process.nextTick = function (fun) {
-    var args = new Array(arguments.length - 1);
-    if (arguments.length > 1) {
-        for (var i = 1; i < arguments.length; i++) {
-            args[i - 1] = arguments[i];
-        }
-    }
-    queue.push(new Item(fun, args));
-    if (queue.length === 1 && !draining) {
-        runTimeout(drainQueue);
-    }
-};
-
-// v8 likes predictible objects
-function Item(fun, array) {
-    this.fun = fun;
-    this.array = array;
-}
-Item.prototype.run = function () {
-    this.fun.apply(null, this.array);
-};
-process.title = 'browser';
-process.browser = true;
-process.env = {};
-process.argv = [];
-process.version = ''; // empty string to avoid regexp issues
-process.versions = {};
-
-function noop() {}
-
-process.on = noop;
-process.addListener = noop;
-process.once = noop;
-process.off = noop;
-process.removeListener = noop;
-process.removeAllListeners = noop;
-process.emit = noop;
-process.prependListener = noop;
-process.prependOnceListener = noop;
-
-process.listeners = function (name) { return [] }
-
-process.binding = function (name) {
-    throw new Error('process.binding is not supported');
-};
-
-process.cwd = function () { return '/' };
-process.chdir = function (dir) {
-    throw new Error('process.chdir is not supported');
-};
-process.umask = function() { return 0; };
-
-
 /***/ }),
 
 /***/ "./node_modules/regenerator-runtime/runtime.js":
@@ -1384,10 +1189,15 @@ var projectX = {
       while (1) {
         switch (_context.prev = _context.next) {
           case 0:
-            _context.next = 2;
+            if (Object(_utils__WEBPACK_IMPORTED_MODULE_2__["isTesting"])()) {
+              _context.next = 3;
+              break;
+            }
+
+            _context.next = 3;
             return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.awrap(Object(_utils__WEBPACK_IMPORTED_MODULE_2__["domReady"])());
 
-          case 2:
+          case 3:
             this.discoverComponents(); // It's easier and more performant to just support Turbolinks than listen
             // to MutationOberserver mutations at the document level.
 
@@ -1398,8 +1208,7 @@ var projectX = {
             observerOptions = {
               childList: true,
               attributes: true,
-              subtree: true //Omit or set to false to observe only changes to the parent node.
-
+              subtree: true
             };
             observer = new MutationObserver(function (mutations) {
               for (var i = 0; i < mutations.length; i++) {
@@ -1416,7 +1225,7 @@ var projectX = {
             });
             observer.observe(targetNode, observerOptions);
 
-          case 8:
+          case 9:
           case "end":
             return _context.stop();
         }
@@ -1432,12 +1241,7 @@ var projectX = {
     });
   },
   initializeElement: function initializeElement(el) {
-    if (Object(_utils__WEBPACK_IMPORTED_MODULE_2__["isTesting"])()) {
-      // This is so the (usually only one) component is accessible to Jest tests.
-      window.component = new _component__WEBPACK_IMPORTED_MODULE_1__["default"](el);
-    } else {
-      new _component__WEBPACK_IMPORTED_MODULE_1__["default"](el);
-    }
+    el.__x = new _component__WEBPACK_IMPORTED_MODULE_1__["default"](el);
   }
 };
 
@@ -1459,7 +1263,7 @@ if (!window.projectX && !Object(_utils__WEBPACK_IMPORTED_MODULE_2__["isTesting"]
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
-/* WEBPACK VAR INJECTION */(function(process) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "domReady", function() { return domReady; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "domReady", function() { return domReady; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isTesting", function() { return isTesting; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "walk", function() { return walk; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "debounce", function() { return debounce; });
@@ -1488,7 +1292,7 @@ function domReady() {
   });
 }
 function isTesting() {
-  return process.env.JEST_WORKER_ID !== undefined;
+  return navigator.userAgent, navigator.userAgent.includes("Node.js") || navigator.userAgent.includes("jsdom");
 }
 function walk(el, callback) {
   callback(el);
@@ -1551,7 +1355,6 @@ function getXAttrs(el, type) {
     return i.type === name;
   });
 }
-/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../node_modules/process/browser.js */ "./node_modules/process/browser.js")))
 
 /***/ }),
 

+ 1 - 1
index.html

@@ -5,7 +5,7 @@
         </style>
 
         <script src="https://cdnjs.cloudflare.com/ajax/libs/turbolinks/5.2.0/turbolinks.js" integrity="sha256-iM4Yzi/zLj/IshPWMC1IluRxTtRjMqjPGd97TZ9yYpU=" crossorigin="anonymous"></script>
-        <script src="https://cdn.jsdelivr.net/gh/calebporzio/project-x/dist/project-x.min.js"></script>
+        <script src="/dist/project-x.min.js"></script>
     </head>
     <body>
         <a href="/link-target">turbo-page</a>

+ 5 - 8
src/index.js

@@ -4,7 +4,9 @@ import { domReady, isTesting } from './utils'
 
 const projectX = {
     start: async function () {
-        await domReady()
+        if (! isTesting()) {
+            await domReady()
+        }
 
         this.discoverComponents()
 
@@ -18,7 +20,7 @@ const projectX = {
         var observerOptions = {
             childList: true,
             attributes: true,
-            subtree: true //Omit or set to false to observe only changes to the parent node.
+            subtree: true,
         }
 
         var observer = new MutationObserver((mutations) => {
@@ -47,12 +49,7 @@ const projectX = {
     },
 
     initializeElement: function (el) {
-        if (isTesting()) {
-            // This is so the (usually only one) component is accessible to Jest tests.
-            window.component = new Component(el)
-        } else {
-            new Component(el)
-        }
+        el.__x = new Component(el)
     }
 }
 

+ 2 - 1
src/utils.js

@@ -12,7 +12,8 @@ export function domReady() {
 }
 
 export function isTesting() {
-    return process.env.JEST_WORKER_ID !== undefined;
+    return navigator.userAgent, navigator.userAgent.includes("Node.js")
+        || navigator.userAgent.includes("jsdom")
 }
 
 export function walk(el, callback) {

+ 5 - 1
test/bind.spec.js

@@ -1,4 +1,8 @@
-import projectX from 'projectX'
+import projectX from 'project-x'
+
+global.MutationObserver = class {
+    observe() {}
+}
 
 test('attribute bindings are set on initialize', async () => {
     document.body.innerHTML = `

+ 46 - 0
test/constructor.spec.js

@@ -0,0 +1,46 @@
+import projectX from 'project-x'
+import { fireEvent, wait } from 'dom-testing-library'
+
+global.MutationObserver = class {
+    observe() {}
+}
+
+test('auto-detect new components and dont loose state of existing ones', async () => {
+    var runObserver
+
+    global.MutationObserver = class {
+        constructor(callback) { runObserver = callback }
+        observe() {}
+    }
+
+    document.body.innerHTML = `
+        <div id="A" x-data="{ foo: '' }">
+            <input x-model="foo">
+            <span x-text="foo"></span>
+        </div>
+    `
+
+    projectX.start()
+
+    fireEvent.input(document.querySelector('input'), { target: { value: 'bar' }})
+
+    await wait(() => { expect(document.querySelector('#A span').innerText).toEqual('bar') })
+
+    const div = document.createElement('div')
+    div.setAttribute('id', 'B')
+    div.setAttribute('x-data', '{ foo: "baz" }')
+    div.innerHTML = `
+        <input x-model="foo">
+        <span x-text="foo"></span>
+    `
+    document.body.appendChild(div)
+
+    runObserver([
+        { addedNodes: [ div ] }
+    ])
+
+    await wait(() => {
+        expect(document.querySelector('#A span').innerText).toEqual('bar')
+        expect(document.querySelector('#B span').innerText).toEqual('baz')
+    })
+})

+ 6 - 2
test/model.spec.js

@@ -1,6 +1,10 @@
-import projectX from 'projectX'
+import projectX from 'project-x'
 import { wait, fireEvent } from 'dom-testing-library'
 
+global.MutationObserver = class {
+    observe() {}
+}
+
 test('x-model has value binding when initialized', async () => {
     document.body.innerHTML = `
         <div x-data="{ foo: 'bar' }">
@@ -38,7 +42,7 @@ test('x-model casts value to number if number modifier is present', async () =>
 
     fireEvent.input(document.querySelector('input'), { target: { value: '123' }})
 
-    await wait(() => { expect(window.component.data.foo).toEqual(123) })
+    await wait(() => { expect(document.querySelector('[x-data]').__x.data.foo).toEqual(123) })
 })
 
 test('x-model trims value if trim modifier is present', async () => {

+ 5 - 1
test/on.spec.js

@@ -1,6 +1,10 @@
-import projectX from 'projectX'
+import projectX from 'project-x'
 import { wait } from 'dom-testing-library'
 
+global.MutationObserver = class {
+    observe() {}
+}
+
 test('data modified in event listener updates effected attribute bindings', async () => {
     document.body.innerHTML = `
         <div x-data="{ foo: 'bar' }">

+ 5 - 1
test/text.spec.js

@@ -1,6 +1,10 @@
-import projectX from 'projectX'
+import projectX from 'project-x'
 import { wait } from 'dom-testing-library'
 
+global.MutationObserver = class {
+    observe() {}
+}
+
 test('x-text on init', async () => {
     document.body.innerHTML = `
         <div x-data="{ foo: 'bar' }">