Skip to content

Commit

Permalink
refactor(*): remove workarounds for IE <9, update IE/Edge-related com…
Browse files Browse the repository at this point in the history
…ments
  • Loading branch information
mgol committed Apr 22, 2017
1 parent ff0e611 commit e4c2fe6
Show file tree
Hide file tree
Showing 18 changed files with 57 additions and 117 deletions.
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ https://plnkr.co or similar (you can use this template as a starting point: http
**Angular version:** 1.x.y
<!-- Check whether this is still an issue in the most recent stable or in the snapshot AngularJS version (https://code.angularjs.org/snapshot/) -->

**Browser:** [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
**Browser:** [all | Chrome XX | Firefox XX | Edge XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
<!-- All browsers where this could be reproduced (and Operating System if relevant) -->

**Anything else:**
<!-- e.g. stacktraces, related issues, suggestions how to fix -->
<!-- e.g. stacktraces, related issues, suggestions how to fix -->
3 changes: 0 additions & 3 deletions docs/config/templates/ngdoc/api/directive.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ <h2 id="usage">Usage</h2>
<ul>
{% if doc.restrict.element %}
<li>as element:
{% if doc.name.indexOf('ng') == 0 -%}
(This directive can be used as custom element, but be aware of <a href="guide/ie">IE restrictions</a>).
{%- endif %}
{% code %}
<{$ doc.name | dashCase $}
{%- for param in doc.params %}
Expand Down
4 changes: 2 additions & 2 deletions docs/content/guide/bootstrap.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ initialization.
<html ng-app>

3. If you choose to use the old style directive syntax `ng:` then include xml-namespace in `html`
to make IE happy. (This is here for historical reasons, and we no longer recommend use of
`ng:`.)
when running the page in the XHTML mode. (This is here for historical reasons, and we no longer
recommend use of `ng:`.)

<html xmlns:ng="http://angularjs.org">

Expand Down
8 changes: 4 additions & 4 deletions docs/content/guide/ie.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<div class="alert alert-warning">
**Note:** AngularJS 1.3 has dropped support for IE8. Read more about it on
[our blog](http://blog.angularjs.org/2013/12/angularjs-13-new-release-approaches.html).
[our blog](https://blog.angularjs.org/2013/12/angularjs-13-new-release-approaches.html).
AngularJS 1.2 will continue to support IE8, but the core team does not plan to spend time
addressing issues specific to IE8 or earlier.
</div>
Expand All @@ -19,16 +19,16 @@ on IE.
The project currently supports and will attempt to fix bugs for IE9 and above. The continuous
integration server runs all the tests against IE9, IE10, and IE11. See
[Travis CI](https://travis-ci.org/angular/angular.js) and
[ci.angularjs.org](http://ci.angularjs.org).
[ci.angularjs.org](https://ci.angularjs.org).

We do not run tests on IE8 and below. A subset of the AngularJS functionality may work on these
browsers, but it is up to you to test and decide whether it works for your particular app.


To ensure your AngularJS application works on IE please consider:

1. Use `ng-style` tags instead of `style="{{ someCss }}"`. The latter works in Chrome and Firefox
but does not work in Internet Explorer <= 11 (the most recent version at time of writing).
1. Use `ng-style` tags instead of `style="{{ someCss }}"`. The latter works in Chrome, Firefox,
Safari and Edge but does not work in Internet Explorer (even 11).
2. For the `type` attribute of buttons, use `ng-attr-type` tags instead of
`type="{{ someExpression }}"`. If using the latter, Internet Explorer overwrites the expression
with `type="submit"` before AngularJS has a chance to interpolate it.
Expand Down
6 changes: 2 additions & 4 deletions docs/content/misc/faq.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,8 @@ We run our extensive test suite against the following browsers: the latest versi
Firefox, Safari, and Safari for iOS, as well as Internet Explorer versions 9-11. See
{@link guide/ie Internet Explorer Compatibility} for more details on supporting legacy IE browsers.

If a browser is untested, it doesn't mean it won't work; for example, older Android (2.3.x)
is supported in the sense that we avoid the dot notation for reserved words as property names,
but we don't actively test changes against it. You can also expect browsers to work that share
a large part of their codebase with a browser we test, such as Opera > version 12
If a browser is untested, it doesn't mean it won't work. You can also expect browsers to work that
share a large part of their codebase with a browser we test, such as Opera 15 or newer
(uses the Blink engine), or the various Firefox derivatives.


Expand Down
10 changes: 3 additions & 7 deletions src/Angular.js
Original file line number Diff line number Diff line change
Expand Up @@ -1353,7 +1353,7 @@ function fromJson(json) {

var ALL_COLONS = /:/g;
function timezoneToOffset(timezone, fallback) {
// Support: IE 9-11 only, Edge 13-14+
// Support: IE 9-11 only, Edge 13-15+
// IE/Edge do not "understand" colon (`:`) in timezone
timezone = timezone.replace(ALL_COLONS, '');
var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
Expand All @@ -1380,12 +1380,7 @@ function convertTimezoneToLocal(date, timezone, reverse) {
* @returns {string} Returns the string representation of the element.
*/
function startingTag(element) {
element = jqLite(element).clone();
try {
// turns out IE does not let you set .html() on elements which
// are not allowed to have children. So we just ignore it.
element.empty();
} catch (e) { /* empty */ }
element = jqLite(element).clone().empty();
var elemHtml = jqLite('<div>').append(element).html();
try {
return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) :
Expand Down Expand Up @@ -1523,6 +1518,7 @@ function allowAutoBootstrap(document) {
var script = document.currentScript;

if (!script) {
// Support: IE 9-11 only
// IE does not have `document.currentScript`
return true;
}
Expand Down
6 changes: 4 additions & 2 deletions src/ng/directive/ngOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,8 @@ var ngOptionsDirective = ['$compile', '$document', '$parse', function($compile,
}


// we can't just jqLite('<option>') since jqLite is not smart enough
// Support: IE 9 only
// We can't just jqLite('<option>') since jqLite is not smart enough
// to create it in <select> and IE barfs otherwise.
var optionTemplate = window.document.createElement('option'),
optGroupTemplate = window.document.createElement('optgroup');
Expand Down Expand Up @@ -611,7 +612,8 @@ var ngOptionsDirective = ['$compile', '$document', '$parse', function($compile,
function updateOptionElement(option, element) {
option.element = element;
element.disabled = option.disabled;
// NOTE: The label must be set before the value, otherwise IE10/11/EDGE create unresponsive
// Support: IE 11 only, Edge 12-13 only
// NOTE: The label must be set before the value, otherwise IE 11 & Edge create unresponsive
// selects in certain circumstances when multiple selects are next to each other and display
// the option list in listbox style, i.e. the select is [multiple], or specifies a [size].
// See https://github.com/angular/angular.js/issues/11314 for more info.
Expand Down
8 changes: 5 additions & 3 deletions src/ng/directive/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
var noopNgModelController = { $setViewValue: noop, $render: noop };

function setOptionSelectedStatus(optionEl, value) {
optionEl.prop('selected', value); // needed for IE
optionEl.prop('selected', value);
/**
* When unselecting an option, setting the property to null / false should be enough
* However, screenreaders might react to the selected attribute instead, see
Expand Down Expand Up @@ -40,6 +40,7 @@ var SelectController =
// does not match any of the options. When it is rendered the value of the unknown
// option is '? XXX ?' where XXX is the hashKey of the value that is not known.
//
// Support: IE 9 only
// We can't just jqLite('<option>') since jqLite is not smart enough
// to create it in <select> and IE barfs otherwise.
self.unknownOption = jqLite(window.document.createElement('option'));
Expand Down Expand Up @@ -625,10 +626,11 @@ var selectDirective = function() {
includes(value, selectCtrl.selectValueMap[option.value]));
var currentlySelected = option.selected;

// IE and Edge, adding options to the selection via shift+click/UP/DOWN,
// Support: IE 9-11 only, Edge 12-15+
// In IE and Edge adding options to the selection via shift+click/UP/DOWN
// will de-select already selected options if "selected" on those options was set
// more than once (i.e. when the options were already selected)
// So we only modify the selected property if neccessary.
// So we only modify the selected property if necessary.
// Note: this behavior cannot be replicated via unit tests because it only shows in the
// actual user interface.
if (shouldBeSelected !== currentlySelected) {
Expand Down
16 changes: 3 additions & 13 deletions src/ngSanitize/sanitize.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,26 +313,15 @@ function $SanitizeProvider() {
return obj;
}

var inertBodyElement;
(function(window) {
var inertBodyElement = (function(window) {
var doc;
if (window.document && window.document.implementation) {
doc = window.document.implementation.createHTMLDocument('inert');
} else {
throw $sanitizeMinErr('noinert', 'Can\'t create an inert html document');
}
var docElement = doc.documentElement || doc.getDocumentElement();
var bodyElements = docElement.getElementsByTagName('body');

// usually there should be only one body element in the document, but IE doesn't have any, so we need to create one
if (bodyElements.length === 1) {
inertBodyElement = bodyElements[0];
} else {
var html = doc.createElement('html');
inertBodyElement = doc.createElement('body');
html.appendChild(inertBodyElement);
doc.appendChild(html);
}
return docElement.getElementsByTagName('body')[0];
})(window);

/**
Expand Down Expand Up @@ -363,6 +352,7 @@ function $SanitizeProvider() {
}
mXSSAttempts--;

// Support: IE 9-11 only
// strip custom-namespaced attributes on IE<=11
if (window.document.documentMode) {
stripCustomNsAttrs(inertBodyElement);
Expand Down
1 change: 1 addition & 0 deletions test/AngularSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1733,6 +1733,7 @@ describe('angular', function() {
dealoc(appElement);
});

// Support: IE 9-11 only
// IE does not support `document.currentScript` (nor extensions with protocol), so skip tests.
if (!msie) {
describe('auto bootstrap restrictions', function() {
Expand Down
4 changes: 2 additions & 2 deletions test/helpers/privateMocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ function xthey(msg, vals, spec) {
}

function browserSupportsCssAnimations() {
// Support: IE < 10
// Only IE10+ support keyframes / transitions
// Support: IE 9 only
// Only IE 10+ support keyframes / transitions
return !(window.document.documentMode < 10);
}

Expand Down
21 changes: 1 addition & 20 deletions test/helpers/testabilityPatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,6 @@ beforeEach(function() {
if (window.publishExternalAPI) {
publishExternalAPI(angular);

// workaround for IE bug https://plus.google.com/104744871076396904202/posts/Kqjuj6RSbbT
// IE overwrite window.jQuery with undefined because of empty jQuery var statement, so we have to
// correct this, but only if we are not running in jqLite mode
if (!_jqLiteMode && _jQuery !== jQuery) {
jQuery = _jQuery;
}

// This resets global id counter;
uid = 0;

Expand Down Expand Up @@ -184,6 +177,7 @@ function sortedHtml(element, showNgClass) {

var attr = attributes[i];
if (attr.name.match(/^ng[:-]/) ||
!/^ng\d+/.test(attr.name) &&
(attr.value || attr.value === '') &&
attr.value !== 'null' &&
attr.value !== 'auto' &&
Expand All @@ -199,19 +193,6 @@ function sortedHtml(element, showNgClass) {
attr.name !== 'tabIndex' &&
attr.name !== 'style' &&
attr.name.substr(0, 6) !== 'jQuery') {
// in IE we need to check for all of these.
if (/ng\d+/.exec(attr.name) ||
attr.name === 'getElementById' ||
// IE7 has `selected` in attributes
attr.name === 'selected' ||
// IE7 adds `value` attribute to all LI tags
(node.nodeName === 'LI' && attr.name === 'value') ||
// IE8 adds bogus rowspan=1 and colspan=1 to TD elements
(node.nodeName === 'TD' && attr.name === 'rowSpan' && attr.value === '1') ||
(node.nodeName === 'TD' && attr.name === 'colSpan' && attr.value === '1')) {
continue;
}

attrs.push(' ' + attr.name + '="' + attr.value + '"');
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/jqLiteSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1368,7 +1368,7 @@ describe('jqLite', function() {
expect(callback).toHaveBeenCalledTimes(1);
});

it('should set event.target on IE', function() {
it('should set event.target', function() {
var elm = jqLite(a);
elm.on('click', function(event) {
expect(event.target).toBe(a);
Expand Down
1 change: 1 addition & 0 deletions test/minErrSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ describe('minErr', function() {
arr, obj, anonFn, namedFn);

expect(myError.message).toContain('[test:26] arr: [1,2,3]; obj: {"a":123,"b":"baar"};');
// Support: IE 9-11 only
// IE does not add space after "function"
expect(myError.message).toMatch(/anonFn: function\s?\(something\);/);
expect(myError.message).toContain('namedFn: function foo(something)');
Expand Down
48 changes: 19 additions & 29 deletions test/ng/compileSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ describe('$compile', function() {
}));

// NOTE: This test may be redundant.
// Support: Edge 14+
// Support: Edge 14-15+
// An `<svg>` element inside a `<foreignObject>` element on MS Edge has no
// size, causing the included `<circle>` element to also have no size and thus fails an
// assertion (relying on the element having a non-zero size).
Expand Down Expand Up @@ -749,36 +749,26 @@ describe('$compile', function() {
element = $compile('<div factory-error template-error linking-error></div>')($rootScope);
expect($exceptionHandler.errors[0]).toEqual('FactoryError');
expect($exceptionHandler.errors[1][0]).toEqual('TemplateError');
expect(ie($exceptionHandler.errors[1][1])).
toEqual('<div factory-error linking-error template-error>');
expect(sortTag($exceptionHandler.errors[1][1])).
toEqual('<div factory-error="" linking-error="" template-error="">');
expect($exceptionHandler.errors[2][0]).toEqual('LinkingError');
expect(ie($exceptionHandler.errors[2][1])).
toEqual('<div class="ng-scope" factory-error linking-error template-error>');


// crazy stuff to make IE happy
function ie(text) {
var list = [],
parts, elementName;

parts = lowercase(text).
replace('<', '').
replace('>', '').
split(' ');
expect(sortTag($exceptionHandler.errors[2][1])).
toEqual('<div class="ng-scope" factory-error="" linking-error="" template-error="">');

// Support: IE 9-11 only, Edge 15+
// IE/Edge sort attributes in a different order.
function sortTag(text) {
var parts, elementName;

parts = text
.replace('<', '')
.replace('>', '')
.split(' ');
elementName = parts.shift();
parts.sort();
parts.unshift(elementName);
forEach(parts, function(value) {
if (value.substring(0,2) !== 'ng') {
value = value.replace('=""', '');
var match = value.match(/=(.*)/);
if (match && match[1].charAt(0) !== '"') {
value = value.replace(/=(.*)/, '="$1"');
}
list.push(value);
}
});
return '<' + list.join(' ') + '>';

return '<' + parts.join(' ') + '>';
}
});
});
Expand Down Expand Up @@ -3358,13 +3348,13 @@ describe('$compile', function() {
it('should translate {{}} in terminal nodes', inject(function($rootScope, $compile) {
element = $compile('<select ng:model="x"><option value="">Greet {{name}}!</option></select>')($rootScope);
$rootScope.$digest();
expect(sortedHtml(element).replace(' selected="true"', '')).
expect(sortedHtml(element).replace(' selected="selected"', '')).
toEqual('<select ng:model="x">' +
'<option value="">Greet !</option>' +
'</select>');
$rootScope.name = 'Misko';
$rootScope.$digest();
expect(sortedHtml(element).replace(' selected="true"', '')).
expect(sortedHtml(element).replace(' selected="selected"', '')).
toEqual('<select ng:model="x">' +
'<option value="">Greet Misko!</option>' +
'</select>');
Expand Down
2 changes: 1 addition & 1 deletion test/ng/directive/booleanAttrsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ describe('ngHref', function() {
expect(element.attr('href')).toEqual(undefined);
}));

// Support: IE 9-11 only, Edge 12-14+
// Support: IE 9-11 only, Edge 12-15+
if (msie || /\bEdge\/[\d.]+\b/.test(window.navigator.userAgent)) {
// IE/Edge fail when setting a href to a URL containing a % that isn't a valid escape sequence
// See https://github.com/angular/angular.js/issues/13388
Expand Down
28 changes: 5 additions & 23 deletions test/ng/locationSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1887,29 +1887,11 @@ describe('$location', function() {
initBrowser({ url: 'http://host.com/base/index.html', basePath: '/base/index.html' }),
setupRewriteChecks(),
function($browser) {
var rightClick;
if (window.document.createEvent) {
rightClick = window.document.createEvent('MouseEvents');
rightClick.initMouseEvent('click', true, true, window, 1, 10, 10, 10, 10, false,
false, false, false, 2, null);

link.dispatchEvent(rightClick);
} else if (window.document.createEventObject) { // for IE
rightClick = window.document.createEventObject();
rightClick.type = 'click';
rightClick.cancelBubble = true;
rightClick.detail = 1;
rightClick.screenX = 10;
rightClick.screenY = 10;
rightClick.clientX = 10;
rightClick.clientY = 10;
rightClick.ctrlKey = false;
rightClick.altKey = false;
rightClick.shiftKey = false;
rightClick.metaKey = false;
rightClick.button = 2;
link.fireEvent('onclick', rightClick);
}
var rightClick = window.document.createEvent('MouseEvents');
rightClick.initMouseEvent('click', true, true, window, 1, 10, 10, 10, 10, false,
false, false, false, 2, null);

link.dispatchEvent(rightClick);
expectNoRewrite($browser);
}
);
Expand Down
Loading

0 comments on commit e4c2fe6

Please sign in to comment.