На этом этапе вы узнаете:
- Как загружать ресурсы извне вашего приложения и добавлять их в DOM через XHR и ObjectURL.
Примерное время выполнения этого шага: 20 минут.
Чтобы просмотреть то, что вы выполните на этом этапе, прыгните вниз этой страницы ↓ .
Как CSP влияет на использование внешних ресурсов
Платформа Chrome Apps обеспечивает полное соответствие вашего приложения политикам безопасности контента (CSP). Вы не можете загружать ресурсы DOM, такие как изображения, шрифты и CSS, напрямую из-за пределов пакета приложения Chrome.
Если вы хотите показать внешнее изображение в своем приложении, вам необходимо запросить его через XMLHttpRequest , преобразовать его в Blob и создать ObjectURL . Этот ObjectURL
можно добавить в DOM, поскольку он ссылается на элемент в памяти в контексте приложения.
Показывать миниатюры для элементов задач
Давайте изменим наше приложение, чтобы оно искало URL-адреса изображений в списке дел. Если URL-адрес выглядит как изображение (например, заканчивается на .png, .jpg, .svg или .gif), примените описанный выше процесс, чтобы отобразить миниатюру изображения рядом с URL-адресом.
Обновить разрешения
В приложении Chrome вы можете выполнять вызовы XMLHttpRequest к любому URL-адресу, если вы указываете его домен в манифесте. Поскольку вы заранее не знаете, какой URL-адрес изображения введет пользователь, запросите разрешение на отправку запросов к "<all_urls>"
.
В файле Manifest.json запросите "
"permissions": ["storage", "alarms", "notifications",
"webview", "<all_urls>"],
Создание и очистка ObjectURL
В контроллере.js добавьте метод _createObjectURL()
для создания URL-адресов ObjectURL из Blob:
Controller.prototype._createObjectURL = function(blob) {
var objURL = URL.createObjectURL(blob);
this.objectURLs = this.objectURLs || [];
this.objectURLs.push(objURL);
return objURL;
};
ObjectURL хранят память, поэтому, когда ObjectURL вам больше не нужен, вам следует отозвать их. Добавьте этот метод _clearObjectURL()
в контроллер.js, чтобы справиться с этим:
Controller.prototype._clearObjectURL = function() {
if (this.objectURLs) {
this.objectURLs.forEach(function(objURL) {
URL.revokeObjectURL(objURL);
});
this.objectURLs = null;
}
};
Сделать запрос XHR
Добавьте метод _requestRemoteImageAndAppend()
для выполнения XMLHttpRequest по заданному URL-адресу изображения:
Controller.prototype._requestRemoteImageAndAppend = function(imageUrl, element) {
var xhr = new XMLHttpRequest();
xhr.open('GET', imageUrl);
xhr.responseType = 'blob';
xhr.onload = function() {
var img = document.createElement('img');
img.setAttribute('data-src', imageUrl);
img.className = 'icon';
var objURL = this._createObjectURL(xhr.response);
img.setAttribute('src', objURL);
element.appendChild(img);
}.bind(this);
xhr.send();
};
При загрузке XHR этот метод создает ObjectURL
из ответа XHR и добавляет элемент <img>
с этим ObjectURL
в DOM.
Анализ URL-адресов изображений в задачах
Теперь добавьте метод _parseForImageURLs()
, который находит все еще не обработанные ссылки и проверяет их на наличие изображений. Для каждого URL-адреса, который выглядит как изображение, выполните _requestRemoteImageAndAppend()
:
Controller.prototype._parseForImageURLs = function () {
// remove old blobs to avoid memory leak:
this._clearObjectURL();
var links = this.$todoList.querySelectorAll('a[data-src]:not(.thumbnail)');
var re = /\.(png|jpg|jpeg|svg|gif)$/;
for (var i = 0; i<links.length; i++) {
var url = links[i].getAttribute('data-src');
if (re.test(url)) {
links[i].classList.add('thumbnail');
this._requestRemoteImageAndAppend(url, links[i]);
}
}
};
Отображение миниатюр в списке задач
Теперь вызовите _parseForImageURLs()
из showAll()
, showActive()
и showCompleted()
:
/**
* An event to fire on load. Will get all items and display them in the
* todo-list
*/
Controller.prototype.showAll = function () {
this.model.read(function (data) {
this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
this._parseForImageURLs();
}.bind(this));
};
/**
* Renders all active tasks
*/
Controller.prototype.showActive = function () {
this.model.read({ completed: 0 }, function (data) {
this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
this._parseForImageURLs();
}.bind(this));
};
/**
* Renders all completed tasks
*/
Controller.prototype.showCompleted = function () {
this.model.read({ completed: 1 }, function (data) {
this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
this._parseForImageURLs();
}.bind(this));
};
Сделайте то же самое для editItem()
:
Controller.prototype.editItem = function (id, label) {
...
var onSaveHandler = function () {
...
if (value.length && !discarding) {
...
label.innerHTML = this._parseForURLs(value);
this._parseForImageURLs();
} else if (value.length === 0) {
...
}
Ограничить размеры отображаемого изображения
Наконец, в _bowerComponents/todomvc-common/base.css добавьте правило CSS, ограничивающее размер изображения:
.thumbnail img[data-src] {
max-width: 100px;
max-height: 28px;
}
Запустите готовое приложение Todo.
Вы закончили Шаг 5! Перезагрузите приложение и добавьте элемент задачи с URL-адресом к изображению, размещенному в Интернете. Некоторые URL-адреса, которые вы можете использовать: http://goo.gl/nqHMF#.jpg или http://goo.gl/HPBGR#.png .
Для получения дополнительной информации
Более подробную информацию о некоторых API, представленных на этом этапе, см.:
Готовы перейти к следующему шагу? Перейдите к шагу 6. Экспорт задач в файловую систему »