Skip to content

Commit 805b8c5

Browse files
committed
Sync with Kendo UI Professional
1 parent 17ec9f9 commit 805b8c5

17 files changed

+81
-16
lines changed

Diff for: docs/api/javascript/kendo.md

+26-2
Original file line numberDiff line numberDiff line change
@@ -315,12 +315,20 @@ The `onChange` method will be executed when the media query is matched or not ma
315315

316316
The `destroy` method will remove the event listeners and destroy the `MediaQueryList` instance. Note that developers should call the `destroy` method when the media query is no longer needed.
317317

318+
You can modify the default [`media queries`](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries) for the adaptive components by modifying the breakpoints defined in `kendo.defaults.breakpoints`. The default break points are defined as:
319+
320+
`kendo.defaults.breakpoints = { small: '(max-width: 700px)', medium: '(min-width: 700.1px) and (max-width: 768px)', large: '(min-width: 768.1px)' }`
321+
318322
#### Parameters
319323

320324
##### media `String`
321325

322326
The media query that will create the [MediaQueryList instance](https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList).
323327

328+
#### Returns
329+
330+
`Object` with the `mediaQueryList` field and the `onChange`, `onEnter`, `onLeave` and `destroy` methods.
331+
324332
#### Example - Using a string
325333

326334
<script>
@@ -359,10 +367,26 @@ The media query that will create the [MediaQueryList instance](https://developer
359367
mediaQueryListener.destroy();
360368
</script>
361369

362-
#### Returns
370+
#### Example - Modify the default breakpoints for the the adaptive components
363371

364-
`Object` with the `mediaQueryList` field and the `onChange`, `onEnter`, `onLeave` and `destroy` methods.
372+
```dojo
373+
<input id="dropdownlist"/>
374+
<script>
375+
let defaultBreakpoints = {
376+
small: '(max-width: 2000px)',
377+
medium: '(min-width: 2000px) and (max-width: 2800px)',
378+
large: '(min-width: 2800px)'
379+
}
380+
381+
kendo.setDefaults('breakpoints', defaultBreakpoints);
365382
383+
$("#dropdownlist").kendoDropDownList({
384+
adaptiveMode:"auto",
385+
dataSource: ["Item1", "Item2"],
386+
value: "Item1"
387+
});
388+
</script>
389+
```
366390

367391

368392
### observableFileManagerData
Loading
-13.7 KB
Binary file not shown.
Loading
-19.2 KB
Binary file not shown.

Diff for: docs/intro/installation/licensing/license-key-ci-services.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,14 @@ steps:
130130
bash
131131
```
132132

133-
![Azure Devops Classic Step 2](../images/azure-devops-classic-step-2.webp)
133+
![Azure Devops Classic Step 2](../images/azure-devops-classic-step-2.png)
134134

135135
```bash
136136
# Activate the license
137137
npx kendo-ui-license activate
138138
```
139139

140-
![Azure Devops Classic Step 3](../images/azure-devops-classic-step-3.webp)
140+
![Azure Devops Classic Step 3](../images/azure-devops-classic-step-3.png)
141141

142142
## See Also
143143

Diff for: src/kendo.bottomnavigation.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export const __meta__ = {
4949

5050
var templates = {
5151
item: template(() => `<span class="${bottomNavigationStyles.item}"></span>`),
52-
anchor: template(({ url }) => `<a class="${bottomNavigationStyles.item}" href="${kendo.htmlEncode(url)}"></a>`),
52+
anchor: template(({ url }) => `<a class="${bottomNavigationStyles.item}" href="${kendo.sanitizeLink(url)}"></a>`),
5353
text: template(({ text }) => `<span class="${bottomNavigationStyles.text}" >${text}</span>`),
5454
icon: template(({ icon }) => kendo.ui.icon($(`<span class="${bottomNavigationStyles.navIcon}"></span>`), { icon: icon, size: "xlarge" }))
5555
};

Diff for: src/kendo.button.menu.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const __meta__ = {
1717
ui = kendo.ui,
1818
keys = kendo.keys,
1919
encode = kendo.htmlEncode,
20+
sanitizeLink = kendo.sanitizeLink,
2021
extend = $.extend,
2122

2223
DOT = ".",
@@ -85,7 +86,7 @@ export const __meta__ = {
8586
`${TEXT_TEMPLATE({ text })}` +
8687
`</span>`;
8788

88-
var LINK_TEMPLATE = ({ url, imageUrl, spriteCssClass, icon, text, attributes }) => `<a href="${encode(url)}" ${attributes.target ? `target="${attributes.target}"` : ''} class="${cssClasses.item}">` +
89+
var LINK_TEMPLATE = ({ url, imageUrl, spriteCssClass, icon, text, attributes }) => `<a href="${sanitizeLink(url)}" ${attributes.target ? `target="${attributes.target}"` : ''} class="${cssClasses.item}">` +
8990
`${IMAGE_TEMPLATE({ imageUrl })}` +
9091
`${SPRITE_TEMPLATE({ spriteCssClass })}` +
9192
`${ICON_TEMPLATE({ icon })}` +

Diff for: src/kendo.buttongroup.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ export const __meta__ = {
285285

286286
items.forEach(function(item, index) {
287287
var text = item.text ? item.encoded === false ? item.text : kendo.htmlEncode(item.text) : "",
288-
el = item.url ? $("<a href=" + item.url + ">") : $("<button>");
288+
el = item.url ? $("<a href=" + kendo.sanitizeLink(item.url) + ">") : $("<button>");
289289

290290
el.html(text);
291291

Diff for: src/kendo.core.js

+20
Original file line numberDiff line numberDiff line change
@@ -2959,6 +2959,25 @@ function pad(number, digits, end) {
29592959
return ("" + value).replace(ampRegExp, "&amp;").replace(ltRegExp, "&lt;").replace(gtRegExp, "&gt;").replace(quoteRegExp, "&quot;").replace(aposRegExp, "&#39;");
29602960
}
29612961

2962+
function sanitizeLink(value) {
2963+
const allowedProtocols = ["http:", "https:"];
2964+
let link = "";
2965+
2966+
try {
2967+
// Use the default origin in case the value is a relative URL.
2968+
const url = new URL(value, window.location.origin);
2969+
if (allowedProtocols.includes(url.protocol)) {
2970+
link = value;
2971+
} else {
2972+
throw new Error("Invalid protocol");
2973+
}
2974+
} catch {
2975+
link = "#INVALIDLINK";
2976+
}
2977+
2978+
return htmlEncode(link);
2979+
}
2980+
29622981
function unescape(value) {
29632982
var template;
29642983

@@ -3126,6 +3145,7 @@ function pad(number, digits, end) {
31263145
stringify: JSON.stringify.bind(JSON),
31273146
eventTarget: eventTarget,
31283147
htmlEncode: htmlEncode,
3148+
sanitizeLink: sanitizeLink,
31293149
unescape: unescape,
31303150
isLocalUrl: function(url) {
31313151
return url && !localUrlRe.test(url);

Diff for: src/kendo.menu.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2468,7 +2468,7 @@ export const __meta__ = {
24682468
var imgAttributes = fieldAccessor("imageAttr")(item);
24692469
var tag = url ? 'a' : 'span';
24702470

2471-
return `<${tag} class='${rendering.textClass(item)}' role='none' ${url ? `href='${url}'` : ''} >` +
2471+
return `<${tag} class='${rendering.textClass(item)}' role='none' ${url ? `href='${kendo.sanitizeLink(url)}'` : ''} >` +
24722472
(imageUrl ? `<img ${rendering.imageCssAttributes(imgAttributes)} alt='' src='${imageUrl}' />` : '') +
24732473
this.templates.sprite(item) +
24742474
this.options.template(data) +

Diff for: src/kendo.tabstrip.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export const __meta__ = {
103103
return result.join(" ");
104104
},
105105
textAttributes: function(item) {
106-
return item.url ? " href='" + item.url + "'" : "";
106+
return item.url ? " href='" + kendo.sanitizeLink(item.url) + "'" : "";
107107
},
108108
text: function(item) {
109109
return item.encoded === false ? item.text : kendo.htmlEncode(item.text);

Diff for: src/kendo.toolbar.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,7 @@ export const __meta__ = {
846846
options.themeColor = PRIMARY;
847847
}
848848
if (options.url) {
849-
widgetElement = $("<a href='" + options.url + "'>");
849+
widgetElement = $("<a href='" + kendo.sanitizeLink(options.url) + "'>");
850850
}
851851
if (options.showIcon === OVERFLOW) {
852852
delete options.imageUrl;

Diff for: tests/tests/core/link-sanitization.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import '@progress/kendo-ui/src/kendo.core.js';
2+
3+
describe("sanitize link", function() {
4+
5+
it("allows http links", function() {
6+
assert.equal(kendo.sanitizeLink("http://telerik.com/"), "http://telerik.com/");
7+
});
8+
9+
it("allows https links", function() {
10+
assert.equal(kendo.sanitizeLink("https://telerik.com/"), "https://telerik.com/");
11+
});
12+
13+
it("allows same page links starting with #", function() {
14+
assert.equal(kendo.sanitizeLink("#test"), "#test");
15+
});
16+
17+
it("sanitizes links that start with javascript:", function() {
18+
assert.equal(kendo.sanitizeLink("javascript:console.log(5)"), "#INVALIDLINK");
19+
});
20+
});

Diff for: tests/tests/menu/datasource.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -223,14 +223,14 @@ describe("Client side rendering", function() {
223223
data: [
224224
{
225225
text: "RootItem",
226-
URLTEST: "URLTEST"
226+
URLTEST: "https://telerik.com/"
227227
}
228228
]
229229
})
230230
});
231231

232232
menu.dataSource.view()[0].load();
233-
assert.equal(menu.element.find(".k-link").attr('href'), "URLTEST");
233+
assert.equal(menu.element.find(".k-link").attr('href'), "https://telerik.com/");
234234
});
235235

236236
it('dataSpriteCssClassField configures the item icon class', function() {

Diff for: tests/tests/tabstrip/databinding.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,10 @@ describe("tabstrip data binding", function() {
113113
it("dataUrlField", function() {
114114
let tabstrip = new kendo.ui.TabStrip(dom, {
115115
dataUrlField: "foo",
116-
dataSource: [{ foo: "http://example.com" }]
116+
dataSource: [{ foo: "http://example.com/" }]
117117
});
118118

119-
assert.equal(tabstrip.tabGroup.find("a").attr("href"), "http://example.com");
119+
assert.equal(tabstrip.tabGroup.find("a").attr("href"), "http://example.com/");
120120
});
121121

122122
it("dataSpriteCssClass", function() {

Diff for: tests/tests/toolbar/rendering.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,13 @@ describe("Toolbar rendering:", function() {
174174
it("url sets a href to the button element if it is an anchor", function() {
175175
container.kendoToolBar({
176176
items: [
177-
{ type: "button", id: "foo", url: "http://www.kendoui.com" }
177+
{ type: "button", id: "foo", url: "http://www.kendoui.com/" }
178178
]
179179
});
180180

181181
let button = container.find("#foo");
182182

183-
assert.isOk(button.attr("href") == "http://www.kendoui.com");
183+
assert.isOk(button.attr("href") == "http://www.kendoui.com/");
184184
});
185185

186186
it("align sets a class to the button element to define its alignment", function() {

0 commit comments

Comments
 (0)