Revert "feat(ivy): added namespaced attributes (#23899)"
This reverts commit d6989c80d3
.
This commit is contained in:
parent
3128b26e5c
commit
07b4c8be42
|
@ -260,11 +260,8 @@ export function injectAttribute(attrNameToInject: string): string|undefined {
|
|||
const attrs = tElement.attrs;
|
||||
if (attrs) {
|
||||
for (let i = 0; i < attrs.length; i = i + 2) {
|
||||
let attrName = attrs[i];
|
||||
const attrName = attrs[i];
|
||||
if (attrName === AttributeMarker.SELECT_ONLY) break;
|
||||
if (attrName === 0) { // NS.FULL
|
||||
attrName = attrs[i += 2];
|
||||
}
|
||||
if (attrName == attrNameToInject) {
|
||||
return attrs[i + 1] as string;
|
||||
}
|
||||
|
|
|
@ -842,28 +842,15 @@ export function createTView(
|
|||
function setUpAttributes(native: RElement, attrs: TAttributes): void {
|
||||
const isProc = isProceduralRenderer(renderer);
|
||||
for (let i = 0; i < attrs.length; i += 2) {
|
||||
let attrName = attrs[i];
|
||||
if (attrName === 0) { // NS.FULL
|
||||
// Namespaced attribute
|
||||
const attrNS = attrs[i + 1] as string;
|
||||
attrName = attrs[i + 2] as string;
|
||||
const attrVal = attrs[i + 3] as string;
|
||||
i += 2;
|
||||
if (isProc) {
|
||||
(renderer as ProceduralRenderer3).setAttribute(native, attrName, attrVal, attrNS);
|
||||
} else {
|
||||
native.setAttributeNS(attrNS, attrName, attrVal);
|
||||
}
|
||||
} else {
|
||||
if (attrName === AttributeMarker.SELECT_ONLY) break;
|
||||
if (attrName !== NG_PROJECT_AS_ATTR_NAME) {
|
||||
const attrVal = attrs[i + 1];
|
||||
ngDevMode && ngDevMode.rendererSetAttribute++;
|
||||
isProc ?
|
||||
(renderer as ProceduralRenderer3)
|
||||
.setAttribute(native, attrName as string, attrVal as string) :
|
||||
native.setAttribute(attrName as string, attrVal as string);
|
||||
}
|
||||
const attrName = attrs[i];
|
||||
if (attrName === AttributeMarker.SELECT_ONLY) break;
|
||||
if (attrName !== NG_PROJECT_AS_ATTR_NAME) {
|
||||
const attrVal = attrs[i + 1];
|
||||
ngDevMode && ngDevMode.rendererSetAttribute++;
|
||||
isProc ?
|
||||
(renderer as ProceduralRenderer3)
|
||||
.setAttribute(native, attrName as string, attrVal as string) :
|
||||
native.setAttribute(attrName as string, attrVal as string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1506,8 +1493,7 @@ function generateInitialInputs(
|
|||
|
||||
const attrs = tNode.attrs !;
|
||||
for (let i = 0; i < attrs.length; i += 2) {
|
||||
const first = attrs[i];
|
||||
const attrName = first === 0 ? attrs[i += 2] : first; // 0 = NS.FULL
|
||||
const attrName = attrs[i];
|
||||
const minifiedInputName = inputs[attrName];
|
||||
const attrValue = attrs[i + 1];
|
||||
|
||||
|
@ -1920,7 +1906,7 @@ function appendToProjectionNode(
|
|||
* - 1 based index of the selector from the {@link projectionDef}
|
||||
*/
|
||||
export function projection(
|
||||
nodeIndex: number, localIndex: number, selectorIndex: number = 0, attrs?: TAttributes): void {
|
||||
nodeIndex: number, localIndex: number, selectorIndex: number = 0, attrs?: string[]): void {
|
||||
const node = createLNode(
|
||||
nodeIndex, TNodeType.Projection, null, null, attrs || null, {head: null, tail: null});
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {LContainer} from './container';
|
||||
import {LInjector} from './injector';
|
||||
import {LProjection} from './projection';
|
||||
|
@ -13,16 +14,6 @@ import {RElement, RNode, RText} from './renderer';
|
|||
import {LView, TData, TView} from './view';
|
||||
|
||||
|
||||
/**
|
||||
* Namespace attribute flags.
|
||||
*/
|
||||
export const enum NS {
|
||||
/**
|
||||
* Use the next value as the full namespaces URI, the values after that
|
||||
* are then the name and the value, respectively.
|
||||
*/
|
||||
FULL = 0,
|
||||
}
|
||||
|
||||
/**
|
||||
* TNodeType corresponds to the TNode.type property. It contains information
|
||||
|
@ -188,7 +179,7 @@ export const enum AttributeMarker {
|
|||
* - attribute names and values
|
||||
* - special markers acting as flags to alter attributes processing.
|
||||
*/
|
||||
export type TAttributes = (string | AttributeMarker | NS)[];
|
||||
export type TAttributes = (string | AttributeMarker)[];
|
||||
|
||||
/**
|
||||
* LNode binding data (flyweight) for a particular node that is shared between all templates
|
||||
|
|
|
@ -106,12 +106,8 @@ function findAttrIndexInNode(name: string, attrs: TAttributes | null): number {
|
|||
if (attrs === null) return -1;
|
||||
for (let i = 0; i < attrs.length; i += step) {
|
||||
const attrName = attrs[i];
|
||||
if (attrName === 0) {
|
||||
// NS.FULL
|
||||
step = 2;
|
||||
} else if (attrName === name) {
|
||||
return i;
|
||||
} else if (attrName === AttributeMarker.SELECT_ONLY) {
|
||||
if (attrName === name) return i;
|
||||
if (attrName === AttributeMarker.SELECT_ONLY) {
|
||||
step = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import {NgForOfContext} from '@angular/common';
|
|||
import {RenderFlags, directiveInject} from '../../src/render3';
|
||||
import {defineComponent} from '../../src/render3/definition';
|
||||
import {bind, container, elementAttribute, elementClass, elementEnd, elementProperty, elementStart, elementStyle, elementStyleNamed, interpolation1, renderTemplate, setHtmlNS, setSvgNS, text, textBinding} from '../../src/render3/instructions';
|
||||
import {LElementNode, LNode, NS} from '../../src/render3/interfaces/node';
|
||||
import {LElementNode, LNode} from '../../src/render3/interfaces/node';
|
||||
import {RElement, domRendererFactory3} from '../../src/render3/interfaces/renderer';
|
||||
import {TrustedString, bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl, sanitizeHtml, sanitizeResourceUrl, sanitizeScript, sanitizeStyle, sanitizeUrl} from '../../src/sanitization/sanitization';
|
||||
import {Sanitizer, SecurityContext} from '../../src/sanitization/security';
|
||||
|
@ -91,43 +91,6 @@ describe('instructions', () => {
|
|||
rendererSetAttribute: 2
|
||||
});
|
||||
});
|
||||
|
||||
it('should use sanitizer function even on elements with namespaced attributes', () => {
|
||||
const t = new TemplateFixture(() => {
|
||||
elementStart(0, 'div', [
|
||||
NS.FULL,
|
||||
'http://www.example.com/2004/test',
|
||||
'whatever',
|
||||
'abc',
|
||||
]);
|
||||
elementEnd();
|
||||
});
|
||||
|
||||
t.update(() => elementAttribute(0, 'title', 'javascript:true', sanitizeUrl));
|
||||
|
||||
|
||||
let standardHTML = '<div whatever="abc" title="unsafe:javascript:true"></div>';
|
||||
let ieHTML = '<div title="unsafe:javascript:true" whatever="abc"></div>';
|
||||
|
||||
expect([standardHTML, ieHTML]).toContain(t.html);
|
||||
|
||||
t.update(
|
||||
() => elementAttribute(
|
||||
0, 'title', bypassSanitizationTrustUrl('javascript:true'), sanitizeUrl));
|
||||
|
||||
standardHTML = '<div whatever="abc" title="javascript:true"></div>';
|
||||
ieHTML = '<div title="javascript:true" whatever="abc"></div>';
|
||||
|
||||
expect([standardHTML, ieHTML]).toContain(t.html);
|
||||
|
||||
expect(ngDevMode).toHaveProperties({
|
||||
firstTemplatePass: 1,
|
||||
tNode: 2,
|
||||
tView: 1,
|
||||
rendererCreateElement: 1,
|
||||
rendererSetAttribute: 2
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('elementProperty', () => {
|
||||
|
@ -445,11 +408,6 @@ describe('instructions', () => {
|
|||
// height="300"
|
||||
'height',
|
||||
'300',
|
||||
// test:title="abc"
|
||||
NS.FULL,
|
||||
'http://www.example.com/2014/test',
|
||||
'title',
|
||||
'abc',
|
||||
]);
|
||||
elementStart(2, 'circle', ['cx', '200', 'cy', '150', 'fill', '#0000ff']);
|
||||
elementEnd();
|
||||
|
@ -461,71 +419,12 @@ describe('instructions', () => {
|
|||
|
||||
// Most browsers will print <circle></circle>, some will print <circle />, both are valid
|
||||
const standardHTML =
|
||||
'<div id="container"><svg id="display" width="400" height="300" title="abc"><circle cx="200" cy="150" fill="#0000ff"></circle></svg></div>';
|
||||
'<div id="container"><svg id="display" width="400" height="300"><circle cx="200" cy="150" fill="#0000ff"></circle></svg></div>';
|
||||
const ie11HTML =
|
||||
'<div id="container"><svg xmlns="http://www.w3.org/2000/svg" xmlns:NS1="http://www.example.com/2014/test" NS1:title="abc" id="display" width="400" height="300"><circle fill="#0000ff" cx="200" cy="150" /></svg></div>';
|
||||
'<div id="container"><svg xmlns="http://www.w3.org/2000/svg" id="display" width="400" height="300"><circle fill="#0000ff" cx="200" cy="150" /></svg></div>';
|
||||
|
||||
expect([standardHTML, ie11HTML]).toContain(t.html);
|
||||
});
|
||||
|
||||
it('should set an attribute with a namespace', () => {
|
||||
const t = new TemplateFixture(() => {
|
||||
elementStart(0, 'div', [
|
||||
'id',
|
||||
'container',
|
||||
// test:title="abc"
|
||||
NS.FULL,
|
||||
'http://www.example.com/2014/test',
|
||||
'title',
|
||||
'abc',
|
||||
]);
|
||||
elementEnd();
|
||||
});
|
||||
|
||||
const standardHTML = '<div id="container" title="abc"></div>';
|
||||
const ie11HTML =
|
||||
'<div id="container" xmlns:NS1="https://www.example.com/2014/test" NS1:title="abc"></div>';
|
||||
expect([standardHTML, ie11HTML]).toContain(t.html);
|
||||
});
|
||||
|
||||
it('should set attributes including more than one namespaced attribute', () => {
|
||||
const t = new TemplateFixture(() => {
|
||||
elementStart(0, 'div', [
|
||||
'id',
|
||||
'container',
|
||||
|
||||
// NS1:title="abc"
|
||||
NS.FULL,
|
||||
'http://www.example.com/2014/test',
|
||||
'title',
|
||||
'abc',
|
||||
|
||||
// style="background: #dead11"
|
||||
'style',
|
||||
'background: #dead11',
|
||||
|
||||
// NS1:whatever="wee"
|
||||
NS.FULL,
|
||||
'http://www.example.com/2014/test',
|
||||
'whatever',
|
||||
'wee',
|
||||
|
||||
// NS2:shazbot="wocka wocka"
|
||||
NS.FULL,
|
||||
'http://www.whatever.com/2016/blah',
|
||||
'shazbot',
|
||||
'wocka wocka',
|
||||
]);
|
||||
elementEnd();
|
||||
});
|
||||
|
||||
const standardHTML =
|
||||
'<div id="container" title="abc" style="background: #dead11" whatever="wee" shazbot="wocka wocka"></div>';
|
||||
const ieHTML =
|
||||
'<div id="container" style="background: rgb(222, 173, 17);" title="abc" whatever="wee" shazbot="wocka wocka"></div>';
|
||||
|
||||
expect([standardHTML, ieHTML]).toContain(t.html);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -28,14 +28,23 @@ import {NAMESPACE_URIS} from '../../src/dom/dom_renderer';
|
|||
|
||||
describe('setAttribute', () => {
|
||||
describe('with namespace', () => {
|
||||
it('xmlns', () => shouldSetAttributeWithNs('xmlns'));
|
||||
it('xml', () => shouldSetAttributeWithNs('xml'));
|
||||
it('svg', () => shouldSetAttributeWithNs('svg'));
|
||||
it('xhtml', () => shouldSetAttributeWithNs('xhtml'));
|
||||
it('xlink', () => shouldSetAttributeWithNs('xlink'));
|
||||
it('custom', () => shouldSetAttributeWithNs('custom'));
|
||||
|
||||
it('unknown', () => {
|
||||
const div = document.createElement('div');
|
||||
expect(div.hasAttribute('unknown:name')).toBe(false);
|
||||
|
||||
renderer.setAttribute(div, 'name', 'value', 'unknown');
|
||||
|
||||
expect(div.getAttribute('unknown:name')).toBe('value');
|
||||
});
|
||||
|
||||
function shouldSetAttributeWithNs(namespace: string): void {
|
||||
const namespaceUri = NAMESPACE_URIS[namespace] || namespace;
|
||||
const namespaceUri = NAMESPACE_URIS[namespace];
|
||||
const div = document.createElement('div');
|
||||
expect(div.hasAttributeNS(namespaceUri, 'name')).toBe(false);
|
||||
|
||||
|
@ -48,16 +57,26 @@ import {NAMESPACE_URIS} from '../../src/dom/dom_renderer';
|
|||
|
||||
describe('removeAttribute', () => {
|
||||
describe('with namespace', () => {
|
||||
it('xmlns', () => shouldRemoveAttributeWithNs('xmlns'));
|
||||
it('xml', () => shouldRemoveAttributeWithNs('xml'));
|
||||
it('svg', () => shouldRemoveAttributeWithNs('svg'));
|
||||
it('xhtml', () => shouldRemoveAttributeWithNs('xhtml'));
|
||||
it('xlink', () => shouldRemoveAttributeWithNs('xlink'));
|
||||
it('custom', () => shouldRemoveAttributeWithNs('custom'));
|
||||
|
||||
it('unknown', () => {
|
||||
const div = document.createElement('div');
|
||||
div.setAttribute('unknown:name', 'value');
|
||||
expect(div.hasAttribute('unknown:name')).toBe(true);
|
||||
|
||||
renderer.removeAttribute(div, 'name', 'unknown');
|
||||
|
||||
expect(div.hasAttribute('unknown:name')).toBe(false);
|
||||
});
|
||||
|
||||
function shouldRemoveAttributeWithNs(namespace: string): void {
|
||||
const namespaceUri = NAMESPACE_URIS[namespace] || namespace;
|
||||
const namespaceUri = NAMESPACE_URIS[namespace];
|
||||
const div = document.createElement('div');
|
||||
div.setAttributeNS(namespaceUri, 'name', 'value');
|
||||
div.setAttributeNS(namespaceUri, `${namespace}:name`, 'value');
|
||||
expect(div.hasAttributeNS(namespaceUri, 'name')).toBe(true);
|
||||
|
||||
renderer.removeAttribute(div, 'name', namespace);
|
||||
|
|
Loading…
Reference in New Issue