2.1. Document resources Previous topic Parent topic Child topic Next topic

Let's suppose you want to insert an image into a news article. After using the Picture button of the toolbar to insert an <img> element and double-clicking (or right-clicking) the image placeholder icon, a dialog box reporting an "openResource not implemented" error is displayed. See figure below.
Therefore the only way to specify the @src attribute of the newly inserted <img> element is to use the Edit Attributes dialog box. However, after doing that, the image placeholder icon just changes its color from blue to green and you'll not see the image you have specified.

Figure 6-3. The NewsApp web application without any ResourceStorage registered with XMLEditor

This limitation is due to the fact that XMLEditor Opens in new window makes very few assumptions about how documents and also document resources like images, video, audio, are stored by your web application.
This limitation may be removed by implementing a ResourceStorage Opens in new window and registering it with XMLEditor using its resourceStorage Opens in new window property.
A ResourceStorage object must implement:
loadResource(uri) Opens in new window
Load and return the Resource having specified URI.
storeResource(data, uri) Opens in new window
Save resource data (for example, an image File dragged from the desktop and dropped onto the image placeholder icon) to specified URI and return the corresponding newly created Resource.
openResource(options) Opens in new window
Display a dialog box letting the user choose an existing resource and return the chosen Resource object.
A Resource Opens in new window is a very simple object essentially associating the resource URI to the resource data (a JavaScript Blob or File).
The NewsApp web application has a ResourceStorage implementation called NewsStorage and a Resource implementation called NewsResource.

Figure 6-4. Excerpts from apidemo/newsapp.js

class NewsResource extends XXE.Resource {
    constructor(uri, data) {
        super(uri, data);

class NewsStorage extends XXE.ResourceStorage {
    constructor(xmlEditor, newsItems) {
        this._newsItems = newsItems;

    async loadResource(uri) { ... }

    async openResource(options) {
        let uri = await NewsResourceChooser.showDialog(this._newsItems,
        if (uri === null) {
            // Canceled by user.
            return null;
        return this.loadResource(uri);
export class NewsApp {
    async loadNews(rssURL) {
      this._items = items;
      this._xmlEditor.resourceStorage =
            new NewsStorage(this._xmlEditor, items);
NewsStorage.openResource displays a NewsResourceChooser dialog box to let the user choose an image. See figure below.

Figure 6-5. The NewsApp web application having its NewsStorage registered with XMLEditor