<commit_before>import FileManager from './FileManager';
import lang from 'dojo/_base/lang';
import declare from 'dojo/_base/declare';
import string from 'dojo/string';
import convert from 'argos/Convert';
import utility from './Utility';

/**
 * @class crm.AttachmentManager
 *
 * @requires argos.Convert
 * @requires crm.Utility
 * @requires crm.FileManager
 */
const __class = declare('crm.AttachmentManager', null, {
  _fileManager: null,
  _entityContext: null,
  _uploadUrl: '',
  _baseUrl: '',
  _attachmentTemplate: false,
  serviceName: false,
  contractName: 'system',
  resourceKind: 'attachments',
  querySelect: null,
  queryInclude: null,
  _files: null,
  _fileDescriptions: null,
  _filesUploadedCount: 0,
  _fileCount: 0,
  _totalProgress: 0,
  _isUploading: false,
  constructor: function constructor() {
    this.querySelect = [];
    this.queryInclude = [];
    this._files = [];
    this._fileDescriptions = [];
    this._fileManager = new FileManager();
    const service = App.getService(this.serviceName);
    const oldContractName = service.getContractName();
    service.setContractName(this.contractName);
    this._baseUrl = utility.stripQueryArgs(service.getUri().toString());
    this._uploadUrl = `${this._baseUrl}/attachments/file`;
    service.setContractName(oldContractName);
  },
  /**
   * @param {Array} files
   */
  createAttachments: function createAttachments() {},
  createAttachment: function createAttachment(file, mixin) {
    if (!mixin.hasOwnProperty('description')) {
      mixin.description = this._getDefaultDescription(file.name);
    }

    this._files.push(file);
    this._fileDescriptions.push({
      fileName: file.name,
      description: mixin.description,
    });
    this.uploadFiles();
  },
  _getDefaultDescription: function _getDefaultDescription(filename) {
    return filename.replace(/\.[\w]*/, '');
  },
  /**
   * @param {Function} callback
   */
  getAttachmentTemplate: function getAttachmentTemplate() {
    this.requestTemplate(function success(template) {
      this._attachmentTemplate = template;
      this.uploadFiles();
    },
      this.onRequestTemplateFailure
    );
  },
  getAttachmentUrl: function getAttachmentUrl(attachmentId) {
    const fileUrl = `${this._baseUrl}/attachments(\'${attachmentId}\')/file`;
    return fileUrl;
  },
  getAttachmenturlByEntity: function getAttachmenturlByEntity(attachment) {
    let href;
    if (attachment.url) {
      href = attachment.url || '';
      href = (href.indexOf('http') < 0) ? `http://${href}` : href;
    } else {
      href = `${this._baseUrl}/attachments(\'${attachment.$key}\')/file`;
    }
    return href;
  },
  _getFileDescription: function _getFileDescription(fileName) {
    let description = this._getDefaultDescription(fileName);
    for (let i = 0; i < this._fileDescriptions.length; i++) {
      if (fileName === this._fileDescriptions[i].fileName) {
        description = this._fileDescriptions[i].description;
      }
    }
    if ((description === null) || (description === '')) {
      description = this._getDefaultDescription(fileName);
    }
    return description;
  },
  _getAttachmentContextMixin: function _getAttachmentContextMixin() {
    const contextMixin = this._getAttachmentContext();
    return contextMixin;
  },
  _getAttachmentContext: function _getAttachmentContext() {
    let contextData = {};
    const found = App.queryNavigationContext((o) => {
      const context = (o.options && o.options.source) || o;
      if (/^(accounts|contacts|opportunities|tickets|leads|activities|history|userActivities)$/.test(context.resourceKind) && context.key) {
        return true;
      }
      return false;
    });

    const contextView = (found && found.options && found.options.source) || found;
    if (contextView) {
      const view = App.getView(contextView.id);
      const entry = contextView.entry || (view && view.entry) || contextView;

      if (!entry || !entry.$key) {
        return {};
      }

      switch (contextView.resourceKind) {
        case 'accounts':
          contextData = {
            accountId: entry.$key,
            accountName: entry.$descriptor,
          };
          break;
        case 'contacts':
          contextData = {
            contactId: entry.$key,
            contactName: entry.$descriptor,
            accountId: entry.Account.$key,
            accountName: entry.Account.AccountName,
          };
          break;
        case 'opportunities':
          contextData = {
            opportunityId: entry.$key,
            oppDescription: entry.$descriptor,
            accountId: entry.Account.$key,
            accountName: entry.Account.AccountName,
          };
          break;
        case 'tickets':
          contextData = {
            ticketId: entry.$key,
            ticketNumber: entry.$descriptor,
            accountId: entry.Account.$key,
            accountName: entry.Account.AccountName,
            contactId: entry.Contact.$key,
            contactName: entry.Contact.$descriptor,
          };
          break;
        case 'leads':
          contextData = {
            leadId: entry.$key,
            accountName: entry.$descriptor,
          };
          break;
        case 'activities':
          contextData = {
            activityId: utility.getRealActivityId(entry.$key),
            contactId: entry.ContactId,
            contactName: entry.ContactName,
            accountId: entry.AccountId,
            accountName: entry.AccountName,
            opportunityId: entry.OpportunityId,
            ticketId: entry.TicketId,
            leadId: entry.LeadId,
          };
          break;
        case 'userActivities':
          contextData = {
            activityId: utility.getRealActivityId(entry.Activity.$key),
            contactId: entry.Activity.ContactId,
            contactName: entry.Activity.ContactName,
            accountId: entry.Activity.AccountId,
            accountName: entry.Activity.AccountName,
            opportunityId: entry.Activity.OpportunityId,
            ticketId: entry.Activity.TicketId,
            leadId: entry.Activity.LeadId,
          };
          break;
        case 'history':
          contextData = {
            historyId: entry.$key,
            contactId: entry.ContactId,
            contactName: entry.ContactName,
            accountId: entry.AccountId,
            accountName: entry.AccountName,
            opportunityId: entry.OpportunityId,
            ticketId: entry.TicketId,
            leadId: entry.LeadId,
          };
          break;
        default:
          contextData = {
            entityId: entry.$key,
            entityName: contextView.id,
            description: entry.$descriptor,
          };
          break;
      }
    }
    return contextData;
  },
  getService: function getService() {
    return App.getService(this.serviceName); /* if false is passed, the default service will be returned */
  },
  createTemplateRequest: function createTemplateRequest() {
    const request = new Sage.SData.Client.SDataTemplateResourceRequest(this.getService());
    request.setResourceKind(this.resourceKind);
    request.setContractName(this.contractName);
    request.setQueryArg(Sage.SData.Client.SDataUri.QueryArgNames.Select, this.querySelect.join(','));
    request.setQueryArg(Sage.SData.Client.SDataUri.QueryArgNames.Include, this.queryInclude.join(','));
    return request;
  },
  requestTemplate: function requestTemplate(onSucess, onFailure) {
    const request = this.createTemplateRequest();
    if (request) {
      request.read({
        success: onSucess,
        failure: onFailure,
        scope: this,
      });
    }
  },
  onRequestTemplateFailure: function onRequestTemplateFailure() {},
  onRequestTemplateSuccess: function onRequestTemplateSuccess(entry) {
    this.processTemplateEntry(entry);
  },
  createDataRequest: function createDataRequest(id) {
    const request = new Sage.SData.Client.SDataSingleResourceRequest(this.getService());
    request.setResourceKind(this.resourceKind);
    request.setContractName(this.contractName);
    request.setResourceSelector(string.substitute("'${0}'", [id]));

    request.setQueryArg(Sage.SData.Client.SDataUri.QueryArgNames.Select, this.querySelect.join(','));
    request.setQueryArg(Sage.SData.Client.SDataUri.QueryArgNames.Include, this.queryInclude.join(','));
    request.setQueryArg('_includeFile', 'false');
    return request;
  },
  requestData: function requestData(attachmnetId, onSucess, onFailure) {
    const request = this.createDataRequest(attachmnetId);
    if (request) {
      request.read({
        success: onSucess,
        failure: onFailure,
        scope: this,
      });
    }
  },
  /**
   * @param response
   * @param o
   */
  onRequestDataFailure: function onRequestDataFailure() {},
  uploadFiles: function uploadFiles() {
    this._isUploading = true;
    this._fileCount = this._files.length;
    while (this._files.length > 0) {
      const file = this._files.pop();
      this._fileManager.uploadFile(file,
        this._uploadUrl,
        this._updateProgress,
        this.onSuccessUpload,
        this.onFailedUpload,
        this);
    }
  },
  onSuccessUpload: function onSuccessUpload(request) {
    // the id of the new attachment is buried in the Location response header...
    const url = request.getResponseHeader('Location');
    const re = /'\w+'/g;
    const matches = url.match(re);

    if (matches) {
      const id = matches[0].replace(/'/g, '');
      // now that we have the id, we can fetch it using the SingleEntrySDataStore
      this.requestData(id, function success(attachment) {
        const mixin = this._getAttachmentContextMixin(attachment.fileName);
        if (mixin) {
          attachment.attachDate = convert.toIsoStringFromDate(new Date());
          attachment.dataType = 'R';
          attachment.description = this._getFileDescription(attachment.fileName);
          const a = lang.mixin(attachment, mixin);
          const req = this.createDataRequest(id);
          if (req) {
            req.update(a, {
              success: this.onSuccessUpdate,
              failure: this.onFailedUpdate,
              scope: this,
            });
          }
        }
      },
        this.onRequestDataFailure
      );
    }
  },
  onFailedUpload: function onFailedUpload(resp) {
    const err = new Error('Failed to upload.');
    err.resp = resp;
    throw err;
  },
  _onFailedAdd: function _onFailedAdd(resp) {
    const err = new Error('Failed to save.');
    err.resp = resp;
    throw err;
  },
  /**
   * @param attachment
   */
  onSuccessUpdate: function onSuccessUpdate() {},
  onFailedUpdate: function onFailedUpdate(resp) {
    const err = new Error('Failed to update.');
    err.resp = resp;
    throw err;
  },
  /**
   * @param percent
   */
  onUpdateProgress: function onUpdateProgress() {},
  _updateProgress: function _updateProgress(curFileProgress) {
    let pct = this._totalProgress;

    if (curFileProgress && curFileProgress.lengthComputable) {
      const filePercent = (curFileProgress.loaded / curFileProgress.total) * 100;
      pct = filePercent;
    } else if (curFileProgress) {
      pct = curFileProgress;
    }
    this._totalProgress = pct;

    if (pct < 99) {
      if (this.onUpdateProgress) {
        this.onUpdateProgress(pct);
      }
    } else {
      this._resetCounts();
      if (this.onUpdateProgress) {
        this.onUpdateProgress(100.00);
      }
    }
  },
  _resetCounts: function _resetCounts() {
    this._fileCount = 0;
    this._filesUploadedCount = 0;
    this._isUploading = false;
    this._totalProgress = 0;
  },
  getAttachmentFile: function getAttachmentFile(attachmentId, responseType, onSuccsess) {
    const url = this.getAttachmentUrl(attachmentId);
    this._fileManager.getFile(url, responseType, onSuccsess);
  },
});

lang.setObject('Mobile.SalesLogix.AttachmentManager', __class);
export default __class;
<commit_msg>Remove unnecessary escape chars.<commit_after>import FileManager from './FileManager';
import lang from 'dojo/_base/lang';
import declare from 'dojo/_base/declare';
import string from 'dojo/string';
import convert from 'argos/Convert';
import utility from './Utility';

/**
 * @class crm.AttachmentManager
 *
 * @requires argos.Convert
 * @requires crm.Utility
 * @requires crm.FileManager
 */
const __class = declare('crm.AttachmentManager', null, {
  _fileManager: null,
  _entityContext: null,
  _uploadUrl: '',
  _baseUrl: '',
  _attachmentTemplate: false,
  serviceName: false,
  contractName: 'system',
  resourceKind: 'attachments',
  querySelect: null,
  queryInclude: null,
  _files: null,
  _fileDescriptions: null,
  _filesUploadedCount: 0,
  _fileCount: 0,
  _totalProgress: 0,
  _isUploading: false,
  constructor: function constructor() {
    this.querySelect = [];
    this.queryInclude = [];
    this._files = [];
    this._fileDescriptions = [];
    this._fileManager = new FileManager();
    const service = App.getService(this.serviceName);
    const oldContractName = service.getContractName();
    service.setContractName(this.contractName);
    this._baseUrl = utility.stripQueryArgs(service.getUri().toString());
    this._uploadUrl = `${this._baseUrl}/attachments/file`;
    service.setContractName(oldContractName);
  },
  /**
   * @param {Array} files
   */
  createAttachments: function createAttachments() {},
  createAttachment: function createAttachment(file, mixin) {
    if (!mixin.hasOwnProperty('description')) {
      mixin.description = this._getDefaultDescription(file.name);
    }

    this._files.push(file);
    this._fileDescriptions.push({
      fileName: file.name,
      description: mixin.description,
    });
    this.uploadFiles();
  },
  _getDefaultDescription: function _getDefaultDescription(filename) {
    return filename.replace(/\.[\w]*/, '');
  },
  /**
   * @param {Function} callback
   */
  getAttachmentTemplate: function getAttachmentTemplate() {
    this.requestTemplate(function success(template) {
      this._attachmentTemplate = template;
      this.uploadFiles();
    },
      this.onRequestTemplateFailure
    );
  },
  getAttachmentUrl: function getAttachmentUrl(attachmentId) {
    const fileUrl = `${this._baseUrl}/attachments('${attachmentId}')/file`;
    return fileUrl;
  },
  getAttachmenturlByEntity: function getAttachmenturlByEntity(attachment) {
    let href;
    if (attachment.url) {
      href = attachment.url || '';
      href = (href.indexOf('http') < 0) ? `http://${href}` : href;
    } else {
      href = `${this._baseUrl}/attachments('${attachment.$key}')/file`;
    }
    return href;
  },
  _getFileDescription: function _getFileDescription(fileName) {
    let description = this._getDefaultDescription(fileName);
    for (let i = 0; i < this._fileDescriptions.length; i++) {
      if (fileName === this._fileDescriptions[i].fileName) {
        description = this._fileDescriptions[i].description;
      }
    }
    if ((description === null) || (description === '')) {
      description = this._getDefaultDescription(fileName);
    }
    return description;
  },
  _getAttachmentContextMixin: function _getAttachmentContextMixin() {
    const contextMixin = this._getAttachmentContext();
    return contextMixin;
  },
  _getAttachmentContext: function _getAttachmentContext() {
    let contextData = {};
    const found = App.queryNavigationContext((o) => {
      const context = (o.options && o.options.source) || o;
      if (/^(accounts|contacts|opportunities|tickets|leads|activities|history|userActivities)$/.test(context.resourceKind) && context.key) {
        return true;
      }
      return false;
    });

    const contextView = (found && found.options && found.options.source) || found;
    if (contextView) {
      const view = App.getView(contextView.id);
      const entry = contextView.entry || (view && view.entry) || contextView;

      if (!entry || !entry.$key) {
        return {};
      }

      switch (contextView.resourceKind) {
        case 'accounts':
          contextData = {
            accountId: entry.$key,
            accountName: entry.$descriptor,
          };
          break;
        case 'contacts':
          contextData = {
            contactId: entry.$key,
            contactName: entry.$descriptor,
            accountId: entry.Account.$key,
            accountName: entry.Account.AccountName,
          };
          break;
        case 'opportunities':
          contextData = {
            opportunityId: entry.$key,
            oppDescription: entry.$descriptor,
            accountId: entry.Account.$key,
            accountName: entry.Account.AccountName,
          };
          break;
        case 'tickets':
          contextData = {
            ticketId: entry.$key,
            ticketNumber: entry.$descriptor,
            accountId: entry.Account.$key,
            accountName: entry.Account.AccountName,
            contactId: entry.Contact.$key,
            contactName: entry.Contact.$descriptor,
          };
          break;
        case 'leads':
          contextData = {
            leadId: entry.$key,
            accountName: entry.$descriptor,
          };
          break;
        case 'activities':
          contextData = {
            activityId: utility.getRealActivityId(entry.$key),
            contactId: entry.ContactId,
            contactName: entry.ContactName,
            accountId: entry.AccountId,
            accountName: entry.AccountName,
            opportunityId: entry.OpportunityId,
            ticketId: entry.TicketId,
            leadId: entry.LeadId,
          };
          break;
        case 'userActivities':
          contextData = {
            activityId: utility.getRealActivityId(entry.Activity.$key),
            contactId: entry.Activity.ContactId,
            contactName: entry.Activity.ContactName,
            accountId: entry.Activity.AccountId,
            accountName: entry.Activity.AccountName,
            opportunityId: entry.Activity.OpportunityId,
            ticketId: entry.Activity.TicketId,
            leadId: entry.Activity.LeadId,
          };
          break;
        case 'history':
          contextData = {
            historyId: entry.$key,
            contactId: entry.ContactId,
            contactName: entry.ContactName,
            accountId: entry.AccountId,
            accountName: entry.AccountName,
            opportunityId: entry.OpportunityId,
            ticketId: entry.TicketId,
            leadId: entry.LeadId,
          };
          break;
        default:
          contextData = {
            entityId: entry.$key,
            entityName: contextView.id,
            description: entry.$descriptor,
          };
          break;
      }
    }
    return contextData;
  },
  getService: function getService() {
    return App.getService(this.serviceName); /* if false is passed, the default service will be returned */
  },
  createTemplateRequest: function createTemplateRequest() {
    const request = new Sage.SData.Client.SDataTemplateResourceRequest(this.getService());
    request.setResourceKind(this.resourceKind);
    request.setContractName(this.contractName);
    request.setQueryArg(Sage.SData.Client.SDataUri.QueryArgNames.Select, this.querySelect.join(','));
    request.setQueryArg(Sage.SData.Client.SDataUri.QueryArgNames.Include, this.queryInclude.join(','));
    return request;
  },
  requestTemplate: function requestTemplate(onSucess, onFailure) {
    const request = this.createTemplateRequest();
    if (request) {
      request.read({
        success: onSucess,
        failure: onFailure,
        scope: this,
      });
    }
  },
  onRequestTemplateFailure: function onRequestTemplateFailure() {},
  onRequestTemplateSuccess: function onRequestTemplateSuccess(entry) {
    this.processTemplateEntry(entry);
  },
  createDataRequest: function createDataRequest(id) {
    const request = new Sage.SData.Client.SDataSingleResourceRequest(this.getService());
    request.setResourceKind(this.resourceKind);
    request.setContractName(this.contractName);
    request.setResourceSelector(string.substitute("'${0}'", [id]));

    request.setQueryArg(Sage.SData.Client.SDataUri.QueryArgNames.Select, this.querySelect.join(','));
    request.setQueryArg(Sage.SData.Client.SDataUri.QueryArgNames.Include, this.queryInclude.join(','));
    request.setQueryArg('_includeFile', 'false');
    return request;
  },
  requestData: function requestData(attachmnetId, onSucess, onFailure) {
    const request = this.createDataRequest(attachmnetId);
    if (request) {
      request.read({
        success: onSucess,
        failure: onFailure,
        scope: this,
      });
    }
  },
  /**
   * @param response
   * @param o
   */
  onRequestDataFailure: function onRequestDataFailure() {},
  uploadFiles: function uploadFiles() {
    this._isUploading = true;
    this._fileCount = this._files.length;
    while (this._files.length > 0) {
      const file = this._files.pop();
      this._fileManager.uploadFile(file,
        this._uploadUrl,
        this._updateProgress,
        this.onSuccessUpload,
        this.onFailedUpload,
        this);
    }
  },
  onSuccessUpload: function onSuccessUpload(request) {
    // the id of the new attachment is buried in the Location response header...
    const url = request.getResponseHeader('Location');
    const re = /'\w+'/g;
    const matches = url.match(re);

    if (matches) {
      const id = matches[0].replace(/'/g, '');
      // now that we have the id, we can fetch it using the SingleEntrySDataStore
      this.requestData(id, function success(attachment) {
        const mixin = this._getAttachmentContextMixin(attachment.fileName);
        if (mixin) {
          attachment.attachDate = convert.toIsoStringFromDate(new Date());
          attachment.dataType = 'R';
          attachment.description = this._getFileDescription(attachment.fileName);
          const a = lang.mixin(attachment, mixin);
          const req = this.createDataRequest(id);
          if (req) {
            req.update(a, {
              success: this.onSuccessUpdate,
              failure: this.onFailedUpdate,
              scope: this,
            });
          }
        }
      },
        this.onRequestDataFailure
      );
    }
  },
  onFailedUpload: function onFailedUpload(resp) {
    const err = new Error('Failed to upload.');
    err.resp = resp;
    throw err;
  },
  _onFailedAdd: function _onFailedAdd(resp) {
    const err = new Error('Failed to save.');
    err.resp = resp;
    throw err;
  },
  /**
   * @param attachment
   */
  onSuccessUpdate: function onSuccessUpdate() {},
  onFailedUpdate: function onFailedUpdate(resp) {
    const err = new Error('Failed to update.');
    err.resp = resp;
    throw err;
  },
  /**
   * @param percent
   */
  onUpdateProgress: function onUpdateProgress() {},
  _updateProgress: function _updateProgress(curFileProgress) {
    let pct = this._totalProgress;

    if (curFileProgress && curFileProgress.lengthComputable) {
      const filePercent = (curFileProgress.loaded / curFileProgress.total) * 100;
      pct = filePercent;
    } else if (curFileProgress) {
      pct = curFileProgress;
    }
    this._totalProgress = pct;

    if (pct < 99) {
      if (this.onUpdateProgress) {
        this.onUpdateProgress(pct);
      }
    } else {
      this._resetCounts();
      if (this.onUpdateProgress) {
        this.onUpdateProgress(100.00);
      }
    }
  },
  _resetCounts: function _resetCounts() {
    this._fileCount = 0;
    this._filesUploadedCount = 0;
    this._isUploading = false;
    this._totalProgress = 0;
  },
  getAttachmentFile: function getAttachmentFile(attachmentId, responseType, onSuccsess) {
    const url = this.getAttachmentUrl(attachmentId);
    this._fileManager.getFile(url, responseType, onSuccsess);
  },
});

lang.setObject('Mobile.SalesLogix.AttachmentManager', __class);
export default __class;
<|endoftext|>


<commit_before>var  sony = {
    "error": "OK",
    "limit": 100,
    "offset": 0,
    "number_of_page_results": 9,
    "number_of_total_results": 9,
    "status_code": 1,
    "results": [
        {
            "id": 18,
            "name": "PlayStation Portable"
        },
        {
            "id": 19,
            "name": "PlayStation 2"
        },
        {
            "id": 22,
            "name": "PlayStation"
        },
        {
            "id": 35,
            "name": "PlayStation 3"
        },
        {
            "id": 88,
            "name": "PlayStation Network (PS3)"
        },
        {
            "id": 116,
            "name": "PlayStation Network (PSP)"
        },
        {
            "id": 129,
            "name": "PlayStation Vita"
        },
        {
            "id": 143,
            "name": "PlayStation Network (Vita)"
        },
        {
            "id": 146,
            "name": "PlayStation 4"
        }
    ],
    "version": "1.0"
}

var xbox = {
    "error": "OK",
    "limit": 100,
    "offset": 0,
    "number_of_page_results": 4,
    "number_of_total_results": 4,
    "status_code": 1,
    "results": [
        {
            "id": 20,
            "name": "Xbox 360"
        },
        {
            "id": 32,
            "name": "Xbox"
        },
        {
            "id": 86,
            "name": "Xbox 360 Games Store"
        },
        {
            "id": 145,
            "name": "Xbox One"
        }
    ],
    "version": "1.0"
}<commit_msg>format<commit_after>var  sony = {
    "error": "OK",
    "limit": 100,
    "offset": 0,
    "number_of_page_results": 9,
    "number_of_total_results": 9,
    "status_code": 1,
    "results": [
        {
            "id": 18,
            "name": "PlayStation Portable"
        },
        {
            "id": 19,
            "name": "PlayStation 2"
        },
        {
            "id": 22,
            "name": "PlayStation"
        },
        {
            "id": 35,
            "name": "PlayStation 3"
        },
        {
            "id": 88,
            "name": "PlayStation Network (PS3)"
        },
        {
            "id": 116,
            "name": "PlayStation Network (PSP)"
        },
        {
            "id": 129,
            "name": "PlayStation Vita"
        },
        {
            "id": 143,
            "name": "PlayStation Network (Vita)"
        },
        {
            "id": 146,
            "name": "PlayStation 4"
        }
    ],
    "version": "1.0"
}

var xbox = {
    "error": "OK",
    "limit": 100,
    "offset": 0,
    "number_of_page_results": 4,
    "number_of_total_results": 4,
    "status_code": 1,
    "results": [
        {
            "id": 20,
            "name": "Xbox 360"
        },
        {
            "id": 32,
            "name": "Xbox"
        },
        {
            "id": 86,
            "name": "Xbox 360 Games Store"
        },
        {
            "id": 145,
            "name": "Xbox One"
        }
    ],
    "version": "1.0"
}
<|endoftext|>


<commit_before>/* eslint-env browser */
self.addEventListener('install', event => event.waitUntil(
  caches.open('funda-v1-core')
    .then(cache => cache.addAll([
      '/offline/',
      '/style.css',
      '/reset.min.css',
      '/assets/img/chat-background.jpg',
      '/assets/img/logo.svg',
      '/assets/img/fundapi-avatar.svg',
      '/funda.js'
    ]))
    .then(self.skipWaiting())
));

self.addEventListener('fetch', function(event) {
  const request = event.request;
  event.respondWith(
    fetch(event.request)
      .catch(err => fetchCoreFile(request.url)) //eslint-disable-line no-unused-vars
      .catch(err => fetchCoreFile('/offline/')) //eslint-disable-line no-unused-vars
  );
});

function fetchCoreFile(url) {
  return caches.open('funda-v1-core')
    .then(cache => cache.match(url))
    .then(response => response ? response : Promise.reject());
}
<commit_msg>:sparkles: Added page caching.<commit_after>/* eslint-env browser */
self.addEventListener('install', event => event.waitUntil(
  caches.open('funda-v1-core')
    .then(cache => cache.addAll([
      '/offline/',
      '/style.css',
      '/reset.min.css',
      '/assets/img/chat-background.jpg',
      '/assets/img/logo.svg',
      '/assets/img/fundapi-avatar.svg',
      '/funda.js'
    ]))
    .then(self.skipWaiting())
));

self.addEventListener('fetch', function(event) {
  const request = event.request;
  if(request.mode === 'navigate') {
    event.respondWith(
      fetch(request)
        .then(response => cachePage(request, response))
        .catch(err => fetchCoreFile(request.url)) //eslint-disable-line no-unused-vars
        .catch(err => fetchCoreFile('/offline/')) //eslint-disable-line no-unused-vars
    );
  } else {
    event.respondWith(
      fetch(request)
        .catch(err => fetchCoreFile(request.url)) //eslint-disable-line no-unused-vars
    );
  }
});

function fetchCoreFile(url) {
  return caches.open('funda-v1-core')
    .then(cache => cache.match(url))
    .then(response => response ? response : Promise.reject());
}

function cachePage(request, response) {
  const clonedResponse = response.clone();
  caches.open('funda-v1-pages')
    .then(cache => cache.put(request, clonedResponse));
  return response;
}
<|endoftext|>


<commit_before>var _ = require('lodash'),
    Q = require('q'),
    jsonPath = require('JSONPath'),
    moment = require('moment'),
    program = require('commander'),
    utils = require('./utils'),
    validator = require('validator');

program
  .version(utils.getVersion('..'))
  .option('--api-endpoint <url>', 'set the API endpoint')
  .option('--token <token>', 'set the token');
//.option('--dry-run', 'do not execute actions')
//.option('-D, --debug', 'enable debug mode')

program._events.version = null;
program
  .command('version')
  .description('show the version information')
  .action(function() {
    console.log('Client version: ' + utils.getVersion('..'));
    console.log('Node.js version (client): ' + process.version);
    console.log('OS/Arch (client): ' + process.platform + '/' + process.arch);
    // FIXME: add information about server
  });

program
  .command('ls <type> [conditions...]')
  .alias('select')
  .description('list objects')
  .option('--no-trunc', "don't truncate output")
  .option('-f, --field <field>', 'fields to print', utils.collect, [])
  .option('-q, --quiet', 'only print ids')
  .option('-l, --limit <max_results>', 'limit results to <max_results> items', 50)
  .option('-p, --page <page>', 'use page <page>', 1)
  .option('-a, --all', 'automatically walk paginated results')
  .option('-o, --order <field>', 'order by <field>', '-_updated')
  .action(function(type, conditions, options) {
    var client = utils.newApi(options);

    type = type || '';
    var query = {};
    if (conditions.length) {
      query['where'] = JSON.stringify(utils.castFields(type, conditions));
    }
    if (options.limit) {
      query['max_results'] = options.limit;
    }
    if (options.page) {
      query['page'] = options.page;
    }

    if (options.order) {
      query['sort'] = options.order;
    }

    var url = '/' + type + '?';
    _.forEach(query, function(value, key) {
      url += key + '=' + value + '&';
    });

    var getter = options.all ? 'all' : 'get';
    client[getter](url)
      .then(function(res) {
        if (!res.body._items.length) {
          console.error('No entries');
          return;
        }
        var items = res.body._items;

        // sorting items
        items = _.sortByOrder(items, ['_created'], [false]);

        // quiet mode
        if (options.quiet) {
          console.log(_.pluck(items, '_id').join('\n'));
          return;
        }

        // get all keys
        var keys = _.sortBy(_.difference(
          _.union(_.flatten(_.map(items, _.keys))),
          ['_links', '_etag']
        ));
        if (options.field.length) {
          keys = _.intersection(keys, options.field);
          var difference = _.difference(options.field, keys);
          if (difference.length) {
            utils.error('Unknown fields: ' + difference);
          }
        }
        if (!keys.length) {
          utils.panic('No fields to print');
        }

        var table = utils.newTable({
          head: keys
        });

        _.forEach(items, function(item) {
          var row = [];
          _.forEach(keys, function(key) {

            switch (key) {

              // Dates
            case '_updated':
            case '_created':
              row.push(moment(new Date(item[key])).fromNow());
              break;

              // UUID
            case '_id':
              row.push(utils.truncateUUID(item[key], options.trunc));
              break;

            default:
              var value = (item[key] || '').toString();

              if (validator.isUUID(value)) {
                value = utils.truncateUUID(value, options.trunc);
              }

              if (value.substring(0, 4) == '$2a$') {
                value = '<blowfish>';
              }

              row.push(value);
              break;
            }

          });
          table.push(row);
        });

        console.log(table.toString());
        var meta = res.body._meta;
        if (meta.max_results < meta.total || options.all) {
          console.log('Displaying items: ' + (meta.max_results * (meta.page - 1) + 1) + '-' + (meta.max_results * meta.page) + '/' + meta.total);
        }
      })
      .catch(utils.panic);
  });

program
  .command('cat <item>')
  .alias('show')
  .description('show object')
  .option('--no-trunc', "don't truncate output")
  .option('-f, --format <format>', 'format the output using the given template')
  .action(function(item, options) {
    var client = utils.newApi(options);

    // FIXME: resolve nested fields
    if (item[item.length - 1] == '/') {
      utils.panic("invalid item '" + item + "'");
    }
    utils.searchItems(item, client, function(items) {
      _.forEach(items, function(item) {
        if (options.trunc) {
          delete item._links;
          delete item._etag;
        }
        if (options.format) {
          var parsed = jsonPath.eval(item, '$' + options.format);
          if (typeof(parsed) === 'object' && parsed.length === 1) {
            console.log(parsed[0]);
          } else {
            console.log(parsed);
          }
        } else {
          console.log(JSON.stringify(item, null, 2));
        }
      });
    }, utils.panic);
  });

program
  .command('rm <item>')
  .alias('delete')
  .description('remove an item')
  .action(function(item, options) {
    var client = utils.newApi(options);

    // FIXME: add warning !

    utils.searchItems(item, client, function(items) {
      client.delete(items[0]).then(function(res) {
        console.log('done');
      }).catch(utils.panic);
    }, utils.panic);
  });

program
  .command('touch <type> [fields...]')
  .alias('add')
  .description('create an item')
  .action(function(type, fields, options) {
    var client = utils.newApi(options);

    var input = utils.castFields(type, fields);

    client.post('/' + type, input).then(function(res) {
      console.log(res.body._id);
    }).catch(utils.panic);
  });

program
  .command('update <item> <fields...>')
  .alias('patch')
  .description('update an item')
  .action(function(item, fields, options) {
    var client = utils.newApi(options);

    utils.searchItems(item, client, function(items) {
      var input = utils.castFields(items[0], fields);
      client.patch(items[0], input).then(function(res) {
        console.log(res.body._id);
      }).catch(utils.panic);
    }, utils.panic);
  });

module.exports = program;

module.exports.run = function() {
  program.parse(process.argv);
  if (!process.argv.slice(2).length) {
    program.outputHelp();
  }
};
<commit_msg>Printing non-null rows<commit_after>var _ = require('lodash'),
    Q = require('q'),
    jsonPath = require('JSONPath'),
    moment = require('moment'),
    program = require('commander'),
    utils = require('./utils'),
    validator = require('validator');

program
  .version(utils.getVersion('..'))
  .option('--api-endpoint <url>', 'set the API endpoint')
  .option('--token <token>', 'set the token');
//.option('--dry-run', 'do not execute actions')
//.option('-D, --debug', 'enable debug mode')

program._events.version = null;
program
  .command('version')
  .description('show the version information')
  .action(function() {
    console.log('Client version: ' + utils.getVersion('..'));
    console.log('Node.js version (client): ' + process.version);
    console.log('OS/Arch (client): ' + process.platform + '/' + process.arch);
    // FIXME: add information about server
  });

program
  .command('ls <type> [conditions...]')
  .alias('select')
  .description('list objects')
  .option('--no-trunc', "don't truncate output")
  .option('-f, --field <field>', 'fields to print', utils.collect, [])
  .option('-q, --quiet', 'only print ids')
  .option('-l, --limit <max_results>', 'limit results to <max_results> items', 50)
  .option('-p, --page <page>', 'use page <page>', 1)
  .option('-a, --all', 'automatically walk paginated results')
  .option('-o, --order <field>', 'order by <field>', '-_updated')
  .action(function(type, conditions, options) {
    var client = utils.newApi(options);

    type = type || '';
    var query = {};
    if (conditions.length) {
      query['where'] = JSON.stringify(utils.castFields(type, conditions));
    }
    if (options.limit) {
      query['max_results'] = options.limit;
    }
    if (options.page) {
      query['page'] = options.page;
    }

    if (options.order) {
      query['sort'] = options.order;
    }

    var url = '/' + type + '?';
    _.forEach(query, function(value, key) {
      url += key + '=' + value + '&';
    });

    var getter = options.all ? 'all' : 'get';
    client[getter](url)
      .then(function(res) {
        if (!res.body._items.length) {
          console.error('No entries');
          return;
        }
        var items = res.body._items;

        // sorting items
        items = _.sortByOrder(items, ['_created'], [false]);

        // quiet mode
        if (options.quiet) {
          console.log(_.pluck(items, '_id').join('\n'));
          return;
        }

        // get all keys
        var keys = _.sortBy(_.difference(
          _.union(_.flatten(_.map(items, _.keys))),
          ['_links', '_etag']
        ));
        if (options.field.length) {
          keys = _.intersection(keys, options.field);
          var difference = _.difference(options.field, keys);
          if (difference.length) {
            utils.error('Unknown fields: ' + difference);
          }
        }
        if (!keys.length) {
          utils.panic('No fields to print');
        }

        var table = utils.newTable({
          head: keys
        });

        _.forEach(items, function(item) {
          var row = [];
          _.forEach(keys, function(key) {

            switch (key) {

              // Dates
            case '_updated':
            case '_created':
              row.push(moment(new Date(item[key])).fromNow());
              break;

              // UUID
            case '_id':
              row.push(utils.truncateUUID(item[key], options.trunc));
              break;

            default:
              var value = (item[key] === undefined || item[key] === null)
                ? '' : item[key].toString();

              if (validator.isUUID(value)) {
                value = utils.truncateUUID(value, options.trunc);
              }

              if (value.substring(0, 4) == '$2a$') {
                value = '<blowfish>';
              }

              row.push(value);
              break;
            }

          });
          table.push(row);
        });

        console.log(table.toString());
        var meta = res.body._meta;
        if (meta.max_results < meta.total || options.all) {
          console.log('Displaying items: ' + (meta.max_results * (meta.page - 1) + 1) + '-' + (meta.max_results * meta.page) + '/' + meta.total);
        }
      })
      .catch(utils.panic);
  });

program
  .command('cat <item>')
  .alias('show')
  .description('show object')
  .option('--no-trunc', "don't truncate output")
  .option('-f, --format <format>', 'format the output using the given template')
  .action(function(item, options) {
    var client = utils.newApi(options);

    // FIXME: resolve nested fields
    if (item[item.length - 1] == '/') {
      utils.panic("invalid item '" + item + "'");
    }
    utils.searchItems(item, client, function(items) {
      _.forEach(items, function(item) {
        if (options.trunc) {
          delete item._links;
          delete item._etag;
        }
        if (options.format) {
          var parsed = jsonPath.eval(item, '$' + options.format);
          if (typeof(parsed) === 'object' && parsed.length === 1) {
            console.log(parsed[0]);
          } else {
            console.log(parsed);
          }
        } else {
          console.log(JSON.stringify(item, null, 2));
        }
      });
    }, utils.panic);
  });

program
  .command('rm <item>')
  .alias('delete')
  .description('remove an item')
  .action(function(item, options) {
    var client = utils.newApi(options);

    // FIXME: add warning !

    utils.searchItems(item, client, function(items) {
      client.delete(items[0]).then(function(res) {
        console.log('done');
      }).catch(utils.panic);
    }, utils.panic);
  });

program
  .command('touch <type> [fields...]')
  .alias('add')
  .description('create an item')
  .action(function(type, fields, options) {
    var client = utils.newApi(options);

    var input = utils.castFields(type, fields);

    client.post('/' + type, input).then(function(res) {
      console.log(res.body._id);
    }).catch(utils.panic);
  });

program
  .command('update <item> <fields...>')
  .alias('patch')
  .description('update an item')
  .action(function(item, fields, options) {
    var client = utils.newApi(options);

    utils.searchItems(item, client, function(items) {
      var input = utils.castFields(items[0], fields);
      client.patch(items[0], input).then(function(res) {
        console.log(res.body._id);
      }).catch(utils.panic);
    }, utils.panic);
  });

module.exports = program;

module.exports.run = function() {
  program.parse(process.argv);
  if (!process.argv.slice(2).length) {
    program.outputHelp();
  }
};
<|endoftext|>


<commit_before>/**
 * Given a DOM subtree, wraps it in a list, and puts each line into its own
 * list item.
 *
 * @param {Node} node modified in place.  Its content is pulled into an
 *     HTMLOListElement, and each line is moved into a separate list item.
 *     This requires cloning elements, so the input might not have unique
 *     IDs after numbering.
 */
function numberLines(node, opt_startLineNum) {
  var nocode = /(?:^|\s)nocode(?:\s|$)/;
  var lineBreak = /\r\n?|\n/;

  var document = node.ownerDocument;

  var whitespace;
  if (node.currentStyle) {
    whitespace = node.currentStyle.whiteSpace;
  } else if (window.getComputedStyle) {
    whitespace = document.defaultView.getComputedStyle(node, null)
        .getPropertyValue('white-space');
  }
  // If it's preformatted, then we need to split lines on line breaks
  // in addition to
s.
  var isPreformatted = whitespace && 'pre' === whitespace.substring(0, 3);

  var li = document.createElement('LI');
  while (node.firstChild) {
    li.appendChild(node.firstChild);
  }
  // An array of lines.  We split below, so this is initialized to one
  // un-split line.
  var listItems = [li];

  function walk(node) {
    switch (node.nodeType) {
      case 1:  // Element
        if (nocode.test(node.className)) { console.log('nocode'); break; }
console.log('  el=' + node.nodeName);
        if ('BR' === node.nodeName) {
          breakAfter(node);
          // Discard the
 since it is now flush against a
.
          if (node.parentNode) {
            node.parentNode.removeChild(node);
          }
        } else {
          for (var child = node.firstChild; child; child = child.nextSibling) {
            walk(child);
          }
        }
        break;
      case 3: case 4:  // Text
        if (isPreformatted) {
          var text = node.nodeValue;
          var match = text.match(lineBreak);
          if (match) {
            var firstLine = text.substring(0, match.index);
            node.nodeValue = firstLine;
            var tail = text.substring(match.index + match[0].length);
console.log('split "' + text.replace(/\r\n?|\n/g, '\\n') + '" into "' + firstLine + '" and "' + tail.replace(/\r\n?|\n/g, '\\n') + '"');
            if (tail) {
              var parent = node.parentNode;
              parent.insertBefore(
                  document.createTextNode(tail), node.nextSibling);
            }
            breakAfter(node);
            if (!firstLine) {
              // Don't leave blank text nodes in the DOM.
              node.parentNode.removeChild(node);
            }
          }
        }
        break;
    }
  }

  // Split a line after the given node.
  function breakAfter(lineEndNode) {
    // If there's nothing to the right, then we can skip ending the line
    // here, and move root-wards since splitting just before an end-tag
    // would require us to create a bunch of empty copies.
    while (!lineEndNode.nextSibling) {
      lineEndNode = lineEndNode.parentNode;
      if (!lineEndNode) { return; }
    }

    function breakLeftOf(limit, copy) {
      // Clone shallowly if this node needs to be on both sides of the break.
      var rightSide = copy ? limit.cloneNode(false) : limit;
      var parent = limit.parentNode;
      if (parent) {
        // We clone the parent chain.
        // This helps us resurrect important styling elements that cross lines.
        // E.g. in Foo
Bar
        // should be rewritten to
Foo

Bar
.
        var parentClone = breakLeftOf(parent, 1);
        // Move the clone and everything to the right of the original
        // onto the cloned parent.
        var next = limit.nextSibling;
        parentClone.appendChild(rightSide);
        for (var sibling = next; sibling; sibling = next) {
          next = sibling.nextSibling;
          parentClone.appendChild(sibling);
        }
      }
      return rightSide;
    }

    var split = breakLeftOf(lineEndNode.nextSibling, 0);

    // Walk the parent chain until we reach an unattached LI.
    for (var parent; (parent = split.parentNode);) { split = parent; }
    // Put it on the list of lines for later processing.
    listItems.push(split);
console.log('pushing listItem length=' + listItems.length);
  }

  // Split lines while there are lines left to split.
  for (var i = 0;  // Number of lines that have been split so far.
       i < listItems.length;  // length updated by breakAfter calls.
       ++i) {
console.log('walking list item ' + i + ' : ' + listItems[i].innerHTML.replace(/[\r\n]+/, '\\n'));
    walk(listItems[i]);
  }

  // Make sure numeric indices show correctly.
  if (opt_startLineNum === (opt_startLineNum|0)) {
    listItems[0].setAttribute('value', opt_startLineNum);
  }

  var ol = document.createElement('OL');
  ol.className = 'linenums';
  var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0;
  for (var i = 0, n = listItems.length; i < n; ++i) {
    li = listItems[i];
    // Stick a class on the LIs so that stylesheets can
    // color odd/even rows, or any other row pattern that
    // is co-prime with 10.
    li.className = 'L' + ((i + offset) % 10);
    if (!li.firstChild) {
      li.appendChild(document.createTextNode('\xA0'));
    }
    ol.appendChild(li);
  }

  node.appendChild(ol);
}<commit_msg>logging for IE<commit_after>/**
 * Given a DOM subtree, wraps it in a list, and puts each line into its own
 * list item.
 *
 * @param {Node} node modified in place.  Its content is pulled into an
 *     HTMLOListElement, and each line is moved into a separate list item.
 *     This requires cloning elements, so the input might not have unique
 *     IDs after numbering.
 */
function numberLines(node, opt_startLineNum) {
  var nocode = /(?:^|\s)nocode(?:\s|$)/;
  var lineBreak = /\r\n?|\n/;

  var document = node.ownerDocument;

  var whitespace;
  if (node.currentStyle) {
    whitespace = node.currentStyle.whiteSpace;
  } else if (window.getComputedStyle) {
    whitespace = document.defaultView.getComputedStyle(node, null)
        .getPropertyValue('white-space');
  }
  // If it's preformatted, then we need to split lines on line breaks
  // in addition to
s.
  var isPreformatted = whitespace && 'pre' === whitespace.substring(0, 3);

  var li = document.createElement('LI');
  while (node.firstChild) {
    li.appendChild(node.firstChild);
  }
  // An array of lines.  We split below, so this is initialized to one
  // un-split line.
  var listItems = [li];

  function walk(node) {
    switch (node.nodeType) {
      case 1:  // Element
        if (nocode.test(node.className)) { console.log('nocode'); break; }
console.log('  el=' + node.nodeName);
        if ('BR' === node.nodeName) {
          breakAfter(node);
          // Discard the
 since it is now flush against a
.
          if (node.parentNode) {
            node.parentNode.removeChild(node);
          }
        } else {
          for (var child = node.firstChild; child; child = child.nextSibling) {
            walk(child);
          }
        }
        break;
      case 3: case 4:  // Text
        if (isPreformatted) {
          var text = node.nodeValue;
          var match = text.match(lineBreak);
          if (match) {
            var firstLine = text.substring(0, match.index);
            node.nodeValue = firstLine;
            var tail = text.substring(match.index + match[0].length);
console.log('split "' + text.replace(/\r\n?|\n/g, '\\n') + '" into "' + firstLine + '" and "' + tail.replace(/\r\n?|\n/g, '\\n') + '"');
            if (tail) {
              var parent = node.parentNode;
              parent.insertBefore(
                  document.createTextNode(tail), node.nextSibling);
            }
            breakAfter(node);
            if (!firstLine) {
              // Don't leave blank text nodes in the DOM.
              node.parentNode.removeChild(node);
            }
          }
        }
        break;
    }
  }

  // Split a line after the given node.
  function breakAfter(lineEndNode) {
    // If there's nothing to the right, then we can skip ending the line
    // here, and move root-wards since splitting just before an end-tag
    // would require us to create a bunch of empty copies.
    while (!lineEndNode.nextSibling) {
      lineEndNode = lineEndNode.parentNode;
      if (!lineEndNode) { return; }
    }

    function breakLeftOf(limit, copy) {
      // Clone shallowly if this node needs to be on both sides of the break.
      var rightSide = copy ? limit.cloneNode(false) : limit;
      var parent = limit.parentNode;
      if (parent) {
        // We clone the parent chain.
        // This helps us resurrect important styling elements that cross lines.
        // E.g. in Foo
Bar
        // should be rewritten to
Foo

Bar
.
        var parentClone = breakLeftOf(parent, 1);
        // Move the clone and everything to the right of the original
        // onto the cloned parent.
        var next = limit.nextSibling;
        parentClone.appendChild(rightSide);
        for (var sibling = next; sibling; sibling = next) {
          next = sibling.nextSibling;
          parentClone.appendChild(sibling);
        }
      }
      return rightSide;
    }

    var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);

    // Walk the parent chain until we reach an unattached LI.
    for (var parent; (parent = copiedListItem.parentNode);) { copiedListItem = parent; }
    // Put it on the list of lines for later processing.
    listItems.push(copiedListItem);
console.log('pushing listItem length=' + listItems.length + ', copy=' + copiedListItem.nodeName);
  }

  // Split lines while there are lines left to split.
  for (var i = 0;  // Number of lines that have been split so far.
       i < listItems.length;  // length updated by breakAfter calls.
       ++i) {
console.log('walking list item ' + i + ' : ' + listItems[i].innerHTML.replace(/[\r\n]+/, '\\n'));
    walk(listItems[i]);
  }

  // Make sure numeric indices show correctly.
  if (opt_startLineNum === (opt_startLineNum|0)) {
    listItems[0].setAttribute('value', opt_startLineNum);
  }

  var ol = document.createElement('OL');
  ol.className = 'linenums';
  var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0;
  for (var i = 0, n = listItems.length; i < n; ++i) {
    li = listItems[i];
    // Stick a class on the LIs so that stylesheets can
    // color odd/even rows, or any other row pattern that
    // is co-prime with 10.
    li.className = 'L' + ((i + offset) % 10);
    if (!li.firstChild) {
      li.appendChild(document.createTextNode('\xA0'));
    }
    ol.appendChild(li);
  }

  node.appendChild(ol);
}<|endoftext|>


<commit_before>// @flow
import React, { Component } from 'react'
import { v4 } from 'uuid'
import Icon from 'material-ui/svg-icons/image/crop-landscape'
import TextField from 'material-ui/TextField'
import type {
  LayoutPluginProps,
  ContentPlugin
} from 'ory-editor-core/lib/service/plugin/classes'
import { BottomToolbar } from 'ory-editor-ui'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'

const handleChange = (onChange: (state: any) => void) => (value: string) =>
  onChange({ background: value })

class PluginComponent extends Component {
  state = { hidden: false }
  props: LayoutPluginProps<{}> & { children: any }

  onToggle = () => {
    this.setState({ hidden: !this.state.hidden })
  }

  render() {
    const {
      children,
      focused,
      onChange,
      state: { background, darken = 0.3 }
    } = this.props
    return (
      <MuiThemeProvider muiTheme={getMuiTheme()}>
        <div
          className="ory-plugins-layout-parallax-background"
          style={{
            backgroundImage: `linear-gradient(rgba(0, 0, 0, ${darken}), rgba(0, 0, 0, ${darken})), url('${background}')`
          }}
        >
          <BottomToolbar open={focused}>
            <TextField
              hintText="http://example.com/image.png"
              floatingLabelText="Image location (URL)"
              inputStyle={{ color: 'white' }}
              floatingLabelStyle={{ color: 'white' }}
              hintStyle={{ color: 'grey' }}
              style={{ width: '512px' }}
              value={background}
              onChange={handleChange(onChange)}
            />
          </BottomToolbar>
          {children}
        </div>
      </MuiThemeProvider>
    )
  }
}

export default ({ defaultPlugin }: { defaultPlugin: ContentPlugin }) => ({
  Component: PluginComponent,
  name: 'ory/editor/core/layout/parallax-background',
  version: '0.0.1',

  text: 'Parallax Background',
  IconComponent: <Icon />,

  createInitialChildren: () => ({
    id: v4(),
    rows: [
      {
        id: v4(),
        cells: [
          {
            content: {
              plugin: defaultPlugin,
              state: defaultPlugin.createInitialState()
            },
            id: v4()
          }
        ]
      }
    ]
  })
})
<commit_msg>plugins/layout/parallax: add darken field in toolbar<commit_after>// @flow
import React, { Component } from 'react'
import { v4 } from 'uuid'
import Icon from 'material-ui/svg-icons/image/crop-landscape'
import TextField from 'material-ui/TextField'
import type {
  LayoutPluginProps,
  ContentPlugin
} from 'ory-editor-core/lib/service/plugin/classes'
import { BottomToolbar } from 'ory-editor-ui'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'

const handleChange = (onChange: (state: any) => void, key: string) => (
  e: Event,
  value: string
) => onChange({ [key]: value })

class PluginComponent extends Component {
  state = { hidden: false }
  props: LayoutPluginProps<{}> & { children: any }

  render() {
    const {
      children,
      focused,
      onChange,
      state: { background = '', darken = 0.3 }
    } = this.props
    return (
      <MuiThemeProvider muiTheme={getMuiTheme()}>
        <div
          className="ory-plugins-layout-parallax-background"
          style={{
            backgroundImage: `linear-gradient(rgba(0, 0, 0, ${darken}), rgba(0, 0, 0, ${darken})), url('${background}')`
          }}
        >
          <BottomToolbar open={focused}>
            <TextField
              hintText="http://example.com/image.png"
              floatingLabelText="Image location (URL)"
              inputStyle={{ color: 'white' }}
              floatingLabelStyle={{ color: 'white' }}
              hintStyle={{ color: 'grey' }}
              style={{ width: '256px' }}
              value={background}
              onChange={handleChange(onChange, 'background')}
            />
            <TextField
              hintText="0.3"
              floatingLabelText="Darken level"
              inputStyle={{ color: 'white' }}
              floatingLabelStyle={{ color: 'white' }}
              hintStyle={{ color: 'grey' }}
              style={{ width: '256px' }}
              value={darken}
              onChange={handleChange(onChange, 'darken')}
            />
          </BottomToolbar>
          {children}
        </div>
      </MuiThemeProvider>
    )
  }
}

export default ({ defaultPlugin }: { defaultPlugin: ContentPlugin }) => ({
  Component: PluginComponent,
  name: 'ory/editor/core/layout/parallax-background',
  version: '0.0.1',

  text: 'Parallax Background',
  IconComponent: <Icon />,

  createInitialChildren: () => ({
    id: v4(),
    rows: [
      {
        id: v4(),
        cells: [
          {
            content: {
              plugin: defaultPlugin,
              state: defaultPlugin.createInitialState()
            },
            id: v4()
          }
        ]
      }
    ]
  }),

  handleFocusNextHotKey: () => Promise.reject(),
  handleFocusPreviousHotKey: () => Promise.reject()
})
<|endoftext|>


<commit_before>define([
    'knockout',
    'knockout-mapping',
    'jquery',
    'dropzone',
    'uuid',
    'arches',
    'viewmodels/alert-json',
    'views/components/iiif-viewer',
    'bindings/dropzone'
], function(ko, koMapping, $, Dropzone, uuid, arches, JsonErrorAlertViewModel, IIIFViewerViewmodel) {
    return ko.components.register('manifest-manager', {
        viewModel: function(params) {
            var self = this;

            this.canvasesForDeletion = ko.observableArray([]);
            this.metadataLabel = ko.observable('');
            this.metadataValues = ko.observable('');
            this.mainMenu = ko.observable(true);
            this.editService = ko.observable(false);
            this.createService = ko.observable(true);
            this.remoteManifest = ko.observable(true);
            this.alert = params.alert;
            this.addCanvas = function(canvas) { //the function name needs to be better
                self.canvasesForDeletion.push(canvas);
                self.canvas(canvas.images[0].resource.service['@id']);
            };

            this.removeCanvas = function(canvas) { //the function name needs to be better
                self.canvasesForDeletion.remove(canvas);
                self.canvas(canvas.images[0].resource.service['@id']);
            };

            IIIFViewerViewmodel.apply(this, [params]);
            this.showTabs(false);
            this.mainMenu.subscribe(function(val){
                val || self.showTabs(true);
            });
            this.isManifestDirty = ko.computed(function() {
                return ((ko.unwrap(self.manifestName) !== self.origManifestName) ||
                        (ko.unwrap(self.manifestDescription) !== self.origManifestDescription) ||
                        (ko.unwrap(self.manifestAttribution) !== self.origManifestAttribution) ||
                        (ko.unwrap(self.manifestLogo) !== self.origManifestLogo) ||
                        (ko.unwrap(self.metadataLabel)) ||
                        (ko.unwrap(self.metadataValues)) ||
                        (koMapping.toJSON(self.manifestMetadata) !== self.origManifestMetadata)
                );});

            this.isCanvasDirty = ko.computed(function() {
                return (ko.unwrap(self.canvasLabel) !== self.origCanvasLabel);
            });

            this.uniqueId = uuid.generate();
            this.uniqueidClass = ko.computed(function() {
                return "unique_id_" + self.uniqueId;
            });

            this.formData = new window.FormData();

            this.stagedMetadata = ko.computed(function(){
                var res = {label: self.metadataLabel(), value: self.metadataValues()};
                return res;
            });

            this.updateMetadata = function(){
                this.manifestMetadata.unshift(koMapping.fromJS(this.stagedMetadata()));
                self.metadataLabel(null);
                self.metadataValues(null);
            };

            this.removeMetadata = function(val) {
                this.manifestMetadata.remove(val);
            };

            this.addAllCanvases = function() {
                self.canvases().forEach(function(canvas){
                    if (self.canvasesForDeletion().indexOf(canvas) < 0) {
                        self.canvasesForDeletion.push(canvas);
                    }
                });
            };

            this.clearCanvasSelection = function() {
                self.canvasesForDeletion([]);
            };

            this.reset = function() {
                self.formData.delete("files");
                self.formData = new window.FormData();
                self.clearCanvasSelection();
                self.metadataLabel('');
                self.metadataValues('');
                self.manifestName(self.origManifestName);
                self.manifestAttribution(self.origManifestAttribution);
                self.manifestLogo(self.origManifestLogo);
                self.manifestDescription(self.origManifestDescription);
                self.canvasLabel(self.origCanvasLabel);
                if (self.origManifestMetadata) {
                    self.manifestMetadata.removeAll();
                    JSON.parse(self.origManifestMetadata).forEach(function(entry){
                        self.manifestMetadata.push(koMapping.fromJS(entry));
                    });
                }
                if (self.dropzone) {
                    self.dropzone.removeAllFiles(true);
                }
            };

            this.submitToManifest = function(onSuccess, onError){
                $.ajax({
                    type: "POST",
                    url: arches.urls.manifest_manager,
                    data: self.formData,
                    cache: false,
                    processData: false,
                    contentType: false,
                    success: function(response) {
                        self.reset();
                        self.manifest(response.url);
                        self.getManifestData();
                        if (onSuccess) {
                            onSuccess();
                        }
                    },
                    error: function(response) {
                        self.reset();
                        // eslint-disable-next-line no-console
                        console.log("Failed to save manifest");
                        self.alert(new JsonErrorAlertViewModel('ep-alert-red', response.responseJSON));
                        if (onError) {
                            onError();
                        }
                    }
                });
            };

            this.deleteCanvases = function() {
                self.formData.append("manifest", ko.unwrap(self.manifest));
                self.formData.append("selected_canvases", JSON.stringify(ko.unwrap(self.canvasesForDeletion)));
                self.submitToManifest();
            };

            this.deleteManifest = function(){
                self.formData.append("manifest", ko.unwrap(self.manifest));
                $.ajax({
                    type: "DELETE",
                    url: arches.urls.manifest_manager,
                    data: JSON.stringify({"manifest": ko.unwrap(self.manifest)}),
                    cache: false,
                    processData: false,
                    contentType: false,
                    success: function() {
                        self.reset();
                        self.toggleManifestEditor();
                        self.manifestData(null);
                        self.manifest(null);
                        self.canvas(null);
                        self.manifestName(null);
                        self.manifestDescription(null);
                        self.manifestAttribution(null);
                        self.expandGallery(true);
                        self.mainMenu(true);
                        self.activeTab(undefined);
                    },
                    error: function(response) {
                        self.reset();
                        // eslint-disable-next-line no-console
                        console.log("Failed to delete manifest");
                        self.alert(new JsonErrorAlertViewModel('ep-alert-red', response.responseJSON));
                    }
                });
            };

            this.createManifest = function(fileList){
                Array.from(fileList).forEach(function(file) {
                    self.formData.append("files", file, file.name);
                });
                self.formData.append("manifest_title", ko.unwrap(self.manifestName));
                self.formData.append("manifest_description", ko.unwrap(self.manifestDescription));
                self.formData.append("operation", "create");
                var onSuccess = function() {
                    self.activeTab('manifest');
                    self.mainMenu(false);
                };
                var onError = function() {
                    self.mainMenu(true);
                    self.activeTab(undefined);
                };
                self.submitToManifest(onSuccess, onError);
            };

            this.addFiles = function(fileList) {
                Array.from(fileList).forEach(function(file) {
                    self.formData.append("files", file, file.name);
                });
                self.updateManifest();
            };

            this.updateManifest = function() {
                self.formData.append("manifest_title", ko.unwrap(self.manifestName));
                self.formData.append("manifest_description", ko.unwrap(self.manifestDescription));
                self.formData.append("manifest_attribution", ko.unwrap(self.manifestAttribution));
                self.formData.append("manifest_logo", ko.unwrap(self.manifestLogo));
                self.formData.append("manifest", ko.unwrap(self.manifest));
                self.formData.append("canvas_label", ko.unwrap(self.canvasLabel)); //new label for canvas
                self.formData.append("canvas_id", ko.unwrap(self.canvas)); //canvas id for label change
                self.formData.append("metadata", JSON.stringify(koMapping.toJS(self.manifestMetadata)));
                self.updateCanvas = false;
                self.submitToManifest();
            };

            this.manifestSelectConfig.placeholder = 'Select an Image Service';
            this.manifest.subscribe(function(val){
                self.getManifestData(val);
                self.mainMenu(false);
            });

            this.manifestData.subscribe(function(val){
                if (self.manifest().charAt(0) == '/') {
                    self.remoteManifest(false);
                }
                else {
                    self.remoteManifest(true);
                }
            });

            this.dropzoneOptions4create = {
                url: "arches.urls.root",
                dictDefaultMessage: '',
                autoProcessQueue: false,
                uploadMultiple: true,
                autoQueue: false,
                clickable: ".fileinput-create-button." + this.uniqueidClass(),
                previewsContainer: '#hidden-dz-create-previews',
                init: function() {
                    self.dropzone = this;
                    this.on("addedfiles", self.createManifest);
                    this.on("error", function(file, error) {
                        file.error = error;
                    });
                }
            };

            this.dropzoneOptions = {
                url: "arches.urls.root",
                dictDefaultMessage: '',
                autoProcessQueue: false,
                uploadMultiple: true,
                autoQueue: false,
                clickable: ".fileinput-button." + this.uniqueidClass(),
                previewsContainer: '#hidden-dz-previews',
                init: function() {
                    self.dropzone = this;
                    this.on("addedfiles", self.addFiles);
                    this.on("error", function(file, error) {
                        file.error = error;
                    });
                }
            };
        },
        template: { require: 'text!templates/views/components/plugins/manifest-manager.htm' }
    });
});<commit_msg>Close open tab when switching from local to remote manifest, re #7346<commit_after>define([
    'knockout',
    'knockout-mapping',
    'jquery',
    'dropzone',
    'uuid',
    'arches',
    'viewmodels/alert-json',
    'views/components/iiif-viewer',
    'bindings/dropzone'
], function(ko, koMapping, $, Dropzone, uuid, arches, JsonErrorAlertViewModel, IIIFViewerViewmodel) {
    return ko.components.register('manifest-manager', {
        viewModel: function(params) {
            var self = this;

            this.canvasesForDeletion = ko.observableArray([]);
            this.metadataLabel = ko.observable('');
            this.metadataValues = ko.observable('');
            this.mainMenu = ko.observable(true);
            this.editService = ko.observable(false);
            this.createService = ko.observable(true);
            this.remoteManifest = ko.observable(true);
            this.alert = params.alert;
            this.addCanvas = function(canvas) { //the function name needs to be better
                self.canvasesForDeletion.push(canvas);
                self.canvas(canvas.images[0].resource.service['@id']);
            };

            this.removeCanvas = function(canvas) { //the function name needs to be better
                self.canvasesForDeletion.remove(canvas);
                self.canvas(canvas.images[0].resource.service['@id']);
            };

            IIIFViewerViewmodel.apply(this, [params]);
            this.showTabs(false);
            this.mainMenu.subscribe(function(val){
                val || self.showTabs(true);
            });
            this.isManifestDirty = ko.computed(function() {
                return ((ko.unwrap(self.manifestName) !== self.origManifestName) ||
                        (ko.unwrap(self.manifestDescription) !== self.origManifestDescription) ||
                        (ko.unwrap(self.manifestAttribution) !== self.origManifestAttribution) ||
                        (ko.unwrap(self.manifestLogo) !== self.origManifestLogo) ||
                        (ko.unwrap(self.metadataLabel)) ||
                        (ko.unwrap(self.metadataValues)) ||
                        (koMapping.toJSON(self.manifestMetadata) !== self.origManifestMetadata)
                );});

            this.isCanvasDirty = ko.computed(function() {
                return (ko.unwrap(self.canvasLabel) !== self.origCanvasLabel);
            });

            this.uniqueId = uuid.generate();
            this.uniqueidClass = ko.computed(function() {
                return "unique_id_" + self.uniqueId;
            });

            this.formData = new window.FormData();

            this.stagedMetadata = ko.computed(function(){
                var res = {label: self.metadataLabel(), value: self.metadataValues()};
                return res;
            });

            this.updateMetadata = function(){
                this.manifestMetadata.unshift(koMapping.fromJS(this.stagedMetadata()));
                self.metadataLabel(null);
                self.metadataValues(null);
            };

            this.removeMetadata = function(val) {
                this.manifestMetadata.remove(val);
            };

            this.addAllCanvases = function() {
                self.canvases().forEach(function(canvas){
                    if (self.canvasesForDeletion().indexOf(canvas) < 0) {
                        self.canvasesForDeletion.push(canvas);
                    }
                });
            };

            this.clearCanvasSelection = function() {
                self.canvasesForDeletion([]);
            };

            this.reset = function() {
                self.formData.delete("files");
                self.formData = new window.FormData();
                self.clearCanvasSelection();
                self.metadataLabel('');
                self.metadataValues('');
                self.manifestName(self.origManifestName);
                self.manifestAttribution(self.origManifestAttribution);
                self.manifestLogo(self.origManifestLogo);
                self.manifestDescription(self.origManifestDescription);
                self.canvasLabel(self.origCanvasLabel);
                if (self.origManifestMetadata) {
                    self.manifestMetadata.removeAll();
                    JSON.parse(self.origManifestMetadata).forEach(function(entry){
                        self.manifestMetadata.push(koMapping.fromJS(entry));
                    });
                }
                if (self.dropzone) {
                    self.dropzone.removeAllFiles(true);
                }
            };

            this.submitToManifest = function(onSuccess, onError){
                $.ajax({
                    type: "POST",
                    url: arches.urls.manifest_manager,
                    data: self.formData,
                    cache: false,
                    processData: false,
                    contentType: false,
                    success: function(response) {
                        self.reset();
                        self.manifest(response.url);
                        self.getManifestData();
                        if (onSuccess) {
                            onSuccess();
                        }
                    },
                    error: function(response) {
                        self.reset();
                        // eslint-disable-next-line no-console
                        console.log("Failed to save manifest");
                        self.alert(new JsonErrorAlertViewModel('ep-alert-red', response.responseJSON));
                        if (onError) {
                            onError();
                        }
                    }
                });
            };

            this.deleteCanvases = function() {
                self.formData.append("manifest", ko.unwrap(self.manifest));
                self.formData.append("selected_canvases", JSON.stringify(ko.unwrap(self.canvasesForDeletion)));
                self.submitToManifest();
            };

            this.deleteManifest = function(){
                self.formData.append("manifest", ko.unwrap(self.manifest));
                $.ajax({
                    type: "DELETE",
                    url: arches.urls.manifest_manager,
                    data: JSON.stringify({"manifest": ko.unwrap(self.manifest)}),
                    cache: false,
                    processData: false,
                    contentType: false,
                    success: function() {
                        self.reset();
                        self.toggleManifestEditor();
                        self.manifestData(null);
                        self.manifest(null);
                        self.canvas(null);
                        self.manifestName(null);
                        self.manifestDescription(null);
                        self.manifestAttribution(null);
                        self.expandGallery(true);
                        self.mainMenu(true);
                        self.activeTab(undefined);
                    },
                    error: function(response) {
                        self.reset();
                        // eslint-disable-next-line no-console
                        console.log("Failed to delete manifest");
                        self.alert(new JsonErrorAlertViewModel('ep-alert-red', response.responseJSON));
                    }
                });
            };

            this.createManifest = function(fileList){
                Array.from(fileList).forEach(function(file) {
                    self.formData.append("files", file, file.name);
                });
                self.formData.append("manifest_title", ko.unwrap(self.manifestName));
                self.formData.append("manifest_description", ko.unwrap(self.manifestDescription));
                self.formData.append("operation", "create");
                var onSuccess = function() {
                    self.activeTab('manifest');
                    self.mainMenu(false);
                };
                var onError = function() {
                    self.mainMenu(true);
                    self.activeTab(undefined);
                };
                self.submitToManifest(onSuccess, onError);
            };

            this.addFiles = function(fileList) {
                Array.from(fileList).forEach(function(file) {
                    self.formData.append("files", file, file.name);
                });
                self.updateManifest();
            };

            this.updateManifest = function() {
                self.formData.append("manifest_title", ko.unwrap(self.manifestName));
                self.formData.append("manifest_description", ko.unwrap(self.manifestDescription));
                self.formData.append("manifest_attribution", ko.unwrap(self.manifestAttribution));
                self.formData.append("manifest_logo", ko.unwrap(self.manifestLogo));
                self.formData.append("manifest", ko.unwrap(self.manifest));
                self.formData.append("canvas_label", ko.unwrap(self.canvasLabel)); //new label for canvas
                self.formData.append("canvas_id", ko.unwrap(self.canvas)); //canvas id for label change
                self.formData.append("metadata", JSON.stringify(koMapping.toJS(self.manifestMetadata)));
                self.updateCanvas = false;
                self.submitToManifest();
            };

            this.manifestSelectConfig.placeholder = 'Select an Image Service';
            this.manifest.subscribe(function(val){
                self.getManifestData(val);
                self.mainMenu(false);
            });

            this.manifestData.subscribe(function(val){
                if (self.manifest().charAt(0) == '/') {
                    self.remoteManifest(false);
                }
                else {
                    self.remoteManifest(true);
                    self.hideSidePanel();
                }
            });

            this.dropzoneOptions4create = {
                url: "arches.urls.root",
                dictDefaultMessage: '',
                autoProcessQueue: false,
                uploadMultiple: true,
                autoQueue: false,
                clickable: ".fileinput-create-button." + this.uniqueidClass(),
                previewsContainer: '#hidden-dz-create-previews',
                init: function() {
                    self.dropzone = this;
                    this.on("addedfiles", self.createManifest);
                    this.on("error", function(file, error) {
                        file.error = error;
                    });
                }
            };

            this.dropzoneOptions = {
                url: "arches.urls.root",
                dictDefaultMessage: '',
                autoProcessQueue: false,
                uploadMultiple: true,
                autoQueue: false,
                clickable: ".fileinput-button." + this.uniqueidClass(),
                previewsContainer: '#hidden-dz-previews',
                init: function() {
                    self.dropzone = this;
                    this.on("addedfiles", self.addFiles);
                    this.on("error", function(file, error) {
                        file.error = error;
                    });
                }
            };
        },
        template: { require: 'text!templates/views/components/plugins/manifest-manager.htm' }
    });
});<|endoftext|>