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

[BUGFIX beta] IE10-8 fixes. normalizeProperty expects lowercase prop name #10318

Merged
merged 4 commits into from
Jan 31, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/ember-htmlbars/tests/attr_nodes/data_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ if (Ember.FEATURES.isEnabled('ember-htmlbars-attribute-syntax')) {
});
runAppend(view);

equalInnerHTML(view.element, '<div data-name="&quot;&quot; data-foo=&quot;blah&quot;">Hi!</div>', "attribute is output");
equal(view.element.firstChild.getAttribute('data-name'), '"" data-foo="blah"', "attribute is output");
});

test("path is output", function() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import EmberView from "ember-views/views/view";
import run from "ember-metal/run_loop";
import compile from "ember-template-compiler/system/compile";
import { equalInnerHTML } from "htmlbars-test-helpers";

var view;

Expand All @@ -19,7 +18,7 @@ function canSetFalsyMaxLength() {
if (Ember.FEATURES.isEnabled('ember-htmlbars-attribute-syntax')) {
// jscs:disable validateIndentation

QUnit.module("ember-htmlbars: nonmatching reflection", {
QUnit.module("ember-htmlbars: property", {
teardown: function() {
if (view) {
run(view, view.destroy);
Expand All @@ -32,13 +31,11 @@ test("maxlength sets the property and attribute", function() {
context: { length: 5 },
template: compile("<input maxlength={{length}}>")
});
appendView(view);

equalInnerHTML(view.element, '<input maxlength="5">', "attribute is output");
appendView(view);
equal(view.element.firstChild.maxLength, 5);

Ember.run(view, view.set, 'context.length', 1);
equalInnerHTML(view.element, '<input maxlength="1">', "attribute is modified by property setting");
equal(view.element.firstChild.maxLength, 1);
});

Expand All @@ -47,20 +44,15 @@ test("quoted maxlength sets the property and attribute", function() {
context: { length: 5 },
template: compile("<input maxlength='{{length}}'>")
});
appendView(view);

equalInnerHTML(view.element, '<input maxlength="5">', "attribute is output");
appendView(view);
equal(view.element.firstChild.maxLength, '5');

if (canSetFalsyMaxLength()) {
Ember.run(view, view.set, 'context.length', null);

equalInnerHTML(view.element, '<input maxlength="0">', "attribute is output");
equal(view.element.firstChild.maxLength, 0);
} else {
Ember.run(view, view.set, 'context.length', 1);

equalInnerHTML(view.element, '<input maxlength="1">', "attribute is output");
equal(view.element.firstChild.maxLength, 1);
}
});
Expand Down
8 changes: 8 additions & 0 deletions packages/ember-htmlbars/tests/attr_nodes/sanitized_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import EmberView from "ember-views/views/view";
import compile from "ember-template-compiler/system/compile";
import { SafeString } from "ember-htmlbars/utils/string";
import { runAppend, runDestroy } from "ember-runtime/tests/utils";
import environment from "ember-metal/environment";

var view;

Expand Down Expand Up @@ -34,6 +35,9 @@ var badTags = [
quotedTemplate: compile("<img src='{{url}}'>"),
multipartTemplate: compile("<img src='{{protocol}}{{path}}'>") },
{ tag: 'iframe', attr: 'src',
// Setting an iframe with a bad protocol results in the browser
// being redirected. in IE8. Skip the iframe tests on that platform.
skip: (environment.hasDOM && document.documentMode && document.documentMode <= 8),
unquotedTemplate: compile("<iframe src={{url}}></iframe>"),
quotedTemplate: compile("<iframe src='{{url}}'></iframe>"),
multipartTemplate: compile("<iframe src='{{protocol}}{{path}}'></iframe>") }
Expand All @@ -43,6 +47,10 @@ for (var i=0, l=badTags.length; i<l; i++) {
(function() {
var subject = badTags[i];

if (subject.skip) {
return;
}

test(subject.tag +" "+subject.attr+" is sanitized when using blacklisted protocol", function() {
view = EmberView.create({
context: { url: 'javascript://example.com' },
Expand Down
2 changes: 1 addition & 1 deletion packages/ember-htmlbars/tests/attr_nodes/svg_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ test("unquoted viewBox property is output", function() {
equalInnerHTML(view.element, '<svg viewBox="'+viewBoxString+'"></svg>', "attribute is output");

Ember.run(view, view.set, 'context.viewBoxString', null);
equalInnerHTML(view.element, '<svg></svg>', "attribute is removed");
equal(view.element.getAttribute('svg'), null, "attribute is removed");
});

test("quoted viewBox property is output", function() {
Expand Down
2 changes: 1 addition & 1 deletion packages/ember-htmlbars/tests/helpers/bind_attr_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ test("should be able to bind class attribute via a truthy property with {{bind-a
set(view, 'isNumber', 0);
});

equalInnerHTML(view.element.firstChild.className, undefined, 'removes class');
ok(view.element.firstChild.className !== 'is-truthy', 'removes class');
});

test("should be able to bind class to view attribute with {{bind-attr}}", function() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import compile from "ember-template-compiler/system/compile";
import run from "ember-metal/run_loop";
import { SafeString } from "ember-htmlbars/utils/string";
import { runAppend, runDestroy } from "ember-runtime/tests/utils";
import environment from "ember-metal/environment";

var view;

Expand All @@ -18,6 +19,9 @@ var badTags = [
{ tag: 'a', attr: 'href',
template: compile('<a {{bind-attr href=view.badValue}}></a>') },
{ tag: 'body', attr: 'background',
// IE8 crashes when setting background with
// a javascript: protocol
skip: (environment.hasDOM && document.documentMode && document.documentMode <= 8),
template: compile('<body {{bind-attr background=view.badValue}}></body>') },
{ tag: 'link', attr: 'href',
template: compile('<link {{bind-attr href=view.badValue}}>') },
Expand All @@ -31,6 +35,10 @@ for (var i=0, l=badTags.length; i<l; i++) {
var attr = badTags[i].attr;
var template = badTags[i].template;

if (badTags[i].skip) {
return;
}

test("XSS - should not bind unsafe "+tagName+" "+attr+" values", function() {
view = EmberView.create({
template: template,
Expand Down
5 changes: 4 additions & 1 deletion packages/ember-metal/lib/platform/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
// https://bugs.webkit.org/show_bug.cgi?id=138038 is fixed
//
// REMOVE_USE_STRICT: true
//

import defineProperties from 'ember-metal/platform/define_properties';

/**
@class platform
Expand Down Expand Up @@ -87,7 +90,7 @@ if (!(Object.create && !Object.create(null).hasOwnProperty)) {
}

if (properties !== undefined) {
Object.defineProperties(object, properties);
defineProperties(object, properties);
}

return object;
Expand Down
1 change: 0 additions & 1 deletion packages/ember-runtime/tests/ext/rsvp_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ test('rejections where the errorThrown is a string should wrap the sting in an e
try {
Ember.testing = false;
Ember.onerror = function(error) {
console.log('error', error);
equal(error.message, actualError, 'expected the real error on the jqXHR');
equal(error.__reason_with_error_thrown__, jqXHR, 'also retains a helpful reference to the rejection reason');
};
Expand Down
2 changes: 1 addition & 1 deletion packages/ember-views/lib/system/render_buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ RenderBuffer.prototype = {

if (props) {
for (prop in props) {
var normalizedCase = normalizeProperty(element, prop) || prop;
var normalizedCase = normalizeProperty(element, prop.toLowerCase()) || prop;

this.dom.setPropertyStrict(element, normalizedCase, props[prop]);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/ember-views/lib/views/text_field.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ export default Component.extend(TextSupport, {
'width'
],

defaultLayout: null,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need some feedback here. text fields are input tags. In IE8 an exception is raised if you try to append blank text nodes to an input.

text_field is now a component, so a layout makes sense. Not sure why it is being appended to the view element though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does make sense. <input> cannot have child elements, this is just enforcing that (and preventing errors in IE8).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fwiw @rwjblue and I have discussed ignoring defaultLayout when there is no template or layout on a component.


/**
The `value` attribute of the input element. As the user inputs text, this
property is updated live.
Expand Down
4 changes: 3 additions & 1 deletion packages/ember-views/lib/views/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import {
isStream
} from "ember-metal/streams/utils";
import sanitizeAttributeValue from "ember-views/system/sanitize_attribute_value";
import { normalizeProperty } from "morph/dom-helper/prop";

function K() { return this; }

Expand Down Expand Up @@ -1252,7 +1253,8 @@ var View = CoreView.extend({

attributeValue = get(this, property);

View.applyAttributeBindings(this.renderer._dom, elem, attributeName, attributeValue);
var normalizedName = normalizeProperty(elem, attributeName.toLowerCase()) || attributeName;
View.applyAttributeBindings(this.renderer._dom, elem, normalizedName, attributeValue);
};

this.registerObserver(this, property, observer);
Expand Down
29 changes: 16 additions & 13 deletions packages/ember-views/tests/views/select_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,26 @@ test("should begin disabled if the disabled attribute is true", function() {
ok(select.$().is(":disabled"));
});

test("should begin required if the required attribute is true", function() {
select.set('required', true);
append();
// Browsers before IE10 do not support the required property.
if (document && ('required' in document.createElement('input'))) {
test("should begin required if the required attribute is true", function() {
select.set('required', true);
append();

ok(select.element.required, 'required property is truthy');
});
ok(select.element.required, 'required property is truthy');
});

test("should become required if the required attribute is changed", function() {
append();
ok(!select.element.required, 'required property is falsy');
test("should become required if the required attribute is changed", function() {
append();
ok(!select.element.required, 'required property is falsy');

run(function() { select.set('required', true); });
ok(select.element.required, 'required property is truthy');
run(function() { select.set('required', true); });
ok(select.element.required, 'required property is truthy');

run(function() { select.set('required', false); });
ok(!select.element.required, 'required property is falsy');
});
run(function() { select.set('required', false); });
ok(!select.element.required, 'required property is falsy');
});
}

test("should become disabled if the disabled attribute is changed", function() {
append();
Expand Down
2 changes: 1 addition & 1 deletion packages/ember-views/tests/views/text_field_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ QUnit.module("Ember.TextField", {
}
});

test("should become disabled if the disabled attribute is true", function() {
test("should become disabled if the disabled attribute is true before append", function() {
textField.set('disabled', true);
append();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,17 @@ test("should render attribute bindings", function() {

test("should normalize case for attribute bindings", function() {
view = EmberView.create({
tagName: 'form',
attributeBindings: ['novalidate'],
tagName: 'input',
attributeBindings: ['disAbled'],

novalidate: true // intentionally lowercase
disAbled: true
});

run(function() {
view.createElement();
});

ok(view.$().prop('noValidate'), "sets property with correct case");
ok(view.$().prop('disabled'), "sets property with correct case");
});

test("should update attribute bindings", function() {
Expand Down