Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IE 11 (and lower) #49

Closed
piperh opened this issue Nov 15, 2017 · 14 comments
Closed

IE 11 (and lower) #49

piperh opened this issue Nov 15, 2017 · 14 comments
Labels

Comments

@piperh
Copy link

piperh commented Nov 15, 2017

Thanks for developing and sharing micromodal. Very easy to configure.

The only setback for me, it doesn't appear to work with any version of Explorer, at least on my MAMP setup (is OK with Edge). Is there a way to make it function with IE?

@jmjoines
Copy link

@piperh - it's a browser compatibilty issue with Array.from()

see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

You can add the following to the beginning of the script, which should fix it in IE

// Production steps of ECMA-262, Edition 6, 22.1.2.1
if (!Array.from) {
  Array.from = (function () {
    var toStr = Object.prototype.toString;
    var isCallable = function (fn) {
      return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
    };
    var toInteger = function (value) {
      var number = Number(value);
      if (isNaN(number)) { return 0; }
      if (number === 0 || !isFinite(number)) { return number; }
      return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
    };
    var maxSafeInteger = Math.pow(2, 53) - 1;
    var toLength = function (value) {
      var len = toInteger(value);
      return Math.min(Math.max(len, 0), maxSafeInteger);
    };

    // The length property of the from method is 1.
    return function from(arrayLike/*, mapFn, thisArg */) {
      // 1. Let C be the this value.
      var C = this;

      // 2. Let items be ToObject(arrayLike).
      var items = Object(arrayLike);

      // 3. ReturnIfAbrupt(items).
      if (arrayLike == null) {
        throw new TypeError('Array.from requires an array-like object - not null or undefined');
      }

      // 4. If mapfn is undefined, then let mapping be false.
      var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
      var T;
      if (typeof mapFn !== 'undefined') {
        // 5. else
        // 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
        if (!isCallable(mapFn)) {
          throw new TypeError('Array.from: when provided, the second argument must be a function');
        }

        // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
        if (arguments.length > 2) {
          T = arguments[2];
        }
      }

      // 10. Let lenValue be Get(items, "length").
      // 11. Let len be ToLength(lenValue).
      var len = toLength(items.length);

      // 13. If IsConstructor(C) is true, then
      // 13. a. Let A be the result of calling the [[Construct]] internal method 
      // of C with an argument list containing the single item len.
      // 14. a. Else, Let A be ArrayCreate(len).
      var A = isCallable(C) ? Object(new C(len)) : new Array(len);

      // 16. Let k be 0.
      var k = 0;
      // 17. Repeat, while k < len… (also steps a - h)
      var kValue;
      while (k < len) {
        kValue = items[k];
        if (mapFn) {
          A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
        } else {
          A[k] = kValue;
        }
        k += 1;
      }
      // 18. Let putStatus be Put(A, "length", len, true).
      A.length = len;
      // 20. Return A.
      return A;
    };
  }());
}

@piperh
Copy link
Author

piperh commented Nov 22, 2017

Adding the above before the existing code in micromodal.min.js does change the behaviour in IE but only produces a minimal window containing the closer 'X'. The window does not size to fit the rest of the content. (I'm using IE11 in Windows 10 on a MAMP setup).

@ghosh ghosh added the bug label Nov 29, 2017
@Silisav
Copy link

Silisav commented Jul 18, 2018

Hello, has anyone discovered if there is a way to fully support ie11?

@zabusm
Copy link

zabusm commented Aug 24, 2018

replace $.extend with Object.assign in the script or use a Object.asign polyfill for ie

@qrac
Copy link

qrac commented Sep 25, 2018

Hello, I could support IE 11 by writing code to solve Object.assign and Array.from () before "micro-modal".

/* IE Polyfull */

if (typeof Object.assign != "function") {
  Object.defineProperty(Object, "assign", {
    value: function assign(target, varArgs) {
      "use strict"
      if (target == null) {
        throw new TypeError("Cannot convert undefined or null to object")
      }
      var to = Object(target)
      for (var index = 1; index < arguments.length; index++) {
        var nextSource = arguments[index]
        if (nextSource != null) {
          for (var nextKey in nextSource) {
            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
              to[nextKey] = nextSource[nextKey]
            }
          }
        }
      }
      return to
    },
    writable: true,
    configurable: true
  })
}

if (!Array.from) {
  Array.from = (function() {
    var toStr = Object.prototype.toString
    var isCallable = function(fn) {
      return typeof fn === "function" || toStr.call(fn) === "[object Function]"
    }
    var toInteger = function(value) {
      var number = Number(value)
      if (isNaN(number)) {
        return 0
      }
      if (number === 0 || !isFinite(number)) {
        return number
      }
      return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number))
    }
    var maxSafeInteger = Math.pow(2, 53) - 1
    var toLength = function(value) {
      var len = toInteger(value)
      return Math.min(Math.max(len, 0), maxSafeInteger)
    }

    return function from(arrayLike) {
      var C = this
      var items = Object(arrayLike)
      if (arrayLike == null) {
        throw new TypeError(
          "Array.from requires an array-like object - not null or undefined"
        )
      }
      var mapFn = arguments.length > 1 ? arguments[1] : void undefined
      var T
      if (typeof mapFn !== "undefined") {
        if (!isCallable(mapFn)) {
          throw new TypeError(
            "Array.from: when provided, the second argument must be a function"
          )
        }
        if (arguments.length > 2) {
          T = arguments[2]
        }
      }
      var len = toLength(items.length)
      var A = isCallable(C) ? Object(new C(len)) : new Array(len)
      var k = 0
      var kValue
      while (k < len) {
        kValue = items[k]
        if (mapFn) {
          A[k] =
            typeof T === "undefined"
              ? mapFn(kValue, k)
              : mapFn.call(T, kValue, k)
        } else {
          A[k] = kValue
        }
        k += 1
      }
      A.length = len
      return A
    }
  })()
}

@Larzans
Copy link

Larzans commented Nov 5, 2018

@qrac awesome, thanks, that worked like a charm!

@nicklee
Copy link

nicklee commented Jan 9, 2019

Thanks for the above fix!

Worth mentioning that you could also include baby-polyfill ( https://babeljs.io/docs/en/babel-polyfill ) or es6-object-assign ( https://www.npmjs.com/package/es6-object-assign ) to get this working in IE11!

@sectsect
Copy link

sectsect commented Aug 3, 2019

Solutions

version: 0.4.0

  1. Transpile the module with Babel by modifying the exclude property in your webpack config.
- exclude: /node_modules/,
+ exclude: /node_modules\/(?!(micromodal)\/).*/,
  1. Or, Add a partial polyfill modules in core-js manually.
import 'core-js/modules/es.object.assign';
import 'core-js/modules/es.array.from';
import MicroModal from 'micromodal';

@ghosh
Copy link
Owner

ghosh commented Sep 6, 2019

Thanks for the pollyfill @qrac. Closing this issue and pointing to your answer as an official recommendation.

@ghosh ghosh closed this as completed Sep 6, 2019
@KevinWagnerWave
Copy link

This site overrides Array.from() with an implementation that doesn't support iterables, which could cause Google Maps JavaScript API v3 to not work correctly.

@KevinWagnerWave
Copy link

Using qrac's polyfill.

@HansCz
Copy link

HansCz commented Nov 12, 2019

+1 for @qrac solution

@alexljamin
Copy link

To expand a little bit more on the @sectsect Webpack solution, here is what I ended up with:

module.exports = {
    output: {
        filename: 'main.min.js'
    },
    module: {
        rules: [
          {
            test: /\.m?js$/,
            exclude: /(node_modules|bower_components)\/(?!(micromodal)\/).*/,
            use: {
              loader: 'babel-loader',
              options: {
                presets: [
                  ['@babel/preset-env', {
                    useBuiltIns: "usage",
                    targets: {
                      browsers: "> 2%, ie 11, safari > 9"
                    },
                    corejs: 3
                  }],
                ],
                plugins: ['@babel/plugin-proposal-object-rest-spread']
              }
            }
          }
        ]
      }
};

For this to work you need to have the following dependencies installed:
npm i --save-dev @babel/core @babel/preset-env babel babel-loader core-js

@labmorales
Copy link

Mine only worked on IE11 with Array.from and Object.Assign polyfills with the following change:

key: "getFocusableNodes",
value: function getFocusableNodes() {
   var nodes = this.modal.querySelectorAll(FOCUSABLE_ELEMENTS);
   return Array.apply(void 0, _toConsumableArray(nodes));
}

line 246:

key: "getFocusableNodes",
value: function getFocusableNodes() {
   var nodes = Array.from(this.modal.querySelectorAll(FOCUSABLE_ELEMENTS));
   return Array.apply(void 0, _toConsumableArray(nodes));
}

But i guess it will work without change with the spread polyfill as well. I just didn't want to insert another polyfill.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests