mediapicker
Advanced tools
Comparing version 5.0.2 to 5.0.3
{ | ||
"baseUrl": "//localhost:8081", | ||
"baseUrl": "http://localhost:8081", | ||
"usingVersions": false, | ||
@@ -4,0 +4,0 @@ "html": { |
@@ -85,3 +85,3 @@ var uploads = {}; | ||
const fileId = data.file ? data.file.id : 'error'; | ||
addEvent(fileId, 'upload-finalize-ready', data); | ||
addEvent(fileId, 'upload-error', data); | ||
@@ -114,3 +114,3 @@ if (data.error.name === 'user_token_fetch_fail') { | ||
addEvent(data.file.id, 'upload-finalize-ready', data); | ||
addEvent(data.file.id, 'upload-processing', data); | ||
}); | ||
@@ -117,0 +117,0 @@ |
@@ -6,4 +6,4 @@ import { MediaLocalUpload } from './localUpload'; | ||
constructor(context: MediaPickerContext, config: ModuleConfig); | ||
upload(base64: string, name?: string): void; | ||
upload(base64: string, name: string): void; | ||
private _urltoFile(dataurl, filename); | ||
} |
@@ -10,5 +10,5 @@ import '!style!css!less!./popup.less'; | ||
export declare class MediaPickerBrowser extends MediaLocalUpload { | ||
private _$browseElem; | ||
private _browseElem; | ||
constructor(context: MediaPickerContext, config: ModuleConfig, browserConfig?: BrowserConfig); | ||
browse(): void; | ||
} |
@@ -5,8 +5,7 @@ import { MediaLocalUpload } from './localUpload'; | ||
export declare class MediaPickerClipboard extends MediaLocalUpload { | ||
private _bound; | ||
private _pasteHandler; | ||
constructor(context: MediaPickerContext, config: ModuleConfig); | ||
activate(): void; | ||
deactivate(): void; | ||
private _onFilesPasted(event); | ||
private _getClipboardData(event); | ||
} |
@@ -9,3 +9,2 @@ /// <reference types="node" /> | ||
import { MediaApiData } from '../service/mediaAPI'; | ||
export declare type JQueryBound = (eventObject: JQueryEventObject, ...args: any[]) => any; | ||
export declare const EVENT_NAMES: { | ||
@@ -12,0 +11,0 @@ UPLOAD_START: string; |
@@ -6,12 +6,13 @@ import '!style!css!less!./dropzone.less'; | ||
export interface DropzoneConfig { | ||
container?: JQuery; | ||
container?: HTMLElement; | ||
headless?: boolean; | ||
} | ||
export declare class MediaPickerDropzone extends MediaLocalUpload { | ||
private _$container; | ||
private _$instance; | ||
private _binded; | ||
private _container; | ||
private _instance; | ||
private _headless; | ||
private _uiActive; | ||
private static _dragContainsFiles(e); | ||
private _onDragOver; | ||
private _onDragLeave; | ||
private static _dragContainsFiles(event); | ||
constructor(context: MediaPickerContext, config: ModuleConfig, dropzoneConfig?: DropzoneConfig); | ||
@@ -22,4 +23,2 @@ activate(): void; | ||
private _getDropzoneUI(); | ||
private _onDragOver(e); | ||
private _onDragLeave(e); | ||
private _onDrop(e); | ||
@@ -26,0 +25,0 @@ private emitDragOver(); |
@@ -7,9 +7,9 @@ import '!style!css!less!./popup.less'; | ||
export interface PopupConfig { | ||
container?: JQuery; | ||
container?: HTMLElement; | ||
} | ||
export declare const USER_RECENTS_COLLECTION = "recents"; | ||
export declare class MediaPickerPopup extends MPComponent { | ||
private _$container; | ||
private _$instance; | ||
private _$userMethodsHelper; | ||
private _container; | ||
private _instance; | ||
private _userMethodsHelper; | ||
private _config; | ||
@@ -22,7 +22,8 @@ private _tenantAPIClient; | ||
constructor(context: MediaPickerContext, config: ModuleConfig, popupConfig?: PopupConfig); | ||
show(): Promise<JQuery>; | ||
init(): void; | ||
show(): Promise<undefined>; | ||
cancel(uniqueIdentifier?: string): void; | ||
teardown(): void; | ||
private _emitUploadEvent(eventName, file, additionalData?); | ||
private _show(resolve); | ||
private _show(); | ||
hide(): void; | ||
@@ -29,0 +30,0 @@ setUploadParams(uploadParams: UploadParams): void; |
@@ -28,3 +28,2 @@ export interface Client { | ||
export declare class UserMethodsInteractor { | ||
private _$container; | ||
private _targetWindow; | ||
@@ -36,3 +35,3 @@ private _channelName; | ||
private _handlers; | ||
constructor(_$container: JQuery, _targetWindow: Window, _channelName: string, _apiUrl: string); | ||
constructor(_targetWindow: Window, _channelName: string, _apiUrl: string); | ||
copyFileToTenant(file: File, tenant: Client, tenantCollection?: string, user?: Client): Promise<string>; | ||
@@ -39,0 +38,0 @@ fetchFile(file: FileToFetch, user?: Client): Promise<string>; |
@@ -33,3 +33,3 @@ /// <reference types="node" /> | ||
query: any; | ||
setUploadParams(uploadParams: UploadParams): Promise<void>; | ||
setUploadParams(uploadParams: UploadParams): Promise<undefined>; | ||
giveReadGrants(fileId: string, granteeId: string): Promise<string>; | ||
@@ -36,0 +36,0 @@ putFileIntoCollection(fileId: string, collectionName: string, occurrKey?: string): Promise<boolean>; |
@@ -22,5 +22,5 @@ /// <reference types="node" /> | ||
private _resumable; | ||
private _$nativeForm; | ||
private _hashGenerator; | ||
private _token; | ||
private _dropListener; | ||
constructor(_url: string, _clientId: string, _tokenSource: TokenSource, _uploadParams: UploadParams); | ||
@@ -39,3 +39,3 @@ readonly token: string; | ||
private _generateHashIE(chunk); | ||
private _pollFile(fileId, collection, cb); | ||
private _pollFile(fileId, collection, callback); | ||
private _onFilesAdded(resumableFiles); | ||
@@ -46,3 +46,3 @@ _onChunkingComplete(resumableFile: ResumableFile): void; | ||
private _onFileError(fileObj, errDetails); | ||
_handleUploadError(errName: string, errDetails?: string, uploadId?: string): Promise<{}>; | ||
_handleUploadError(errName: string, errDetails?: string, uploadId?: string): Promise<undefined>; | ||
private _generateHeaders(); | ||
@@ -49,0 +49,0 @@ private _createUpload(); |
{ | ||
"name": "mediapicker", | ||
"version": "5.0.2", | ||
"version": "5.0.3", | ||
"description": "Library for handling file uploads", | ||
@@ -34,3 +34,3 @@ "main": "./lib/mediapicker.js", | ||
"@types/chai-as-promised": "^0.0.29", | ||
"@types/jquery": "^2.0.43", | ||
"@types/domready": "0.0.29", | ||
"@types/mocha": "^2.2.38", | ||
@@ -52,2 +52,3 @@ "@types/node": "^7.0.4", | ||
"dateformat": "^1.0.12", | ||
"domready": "^1.0.8", | ||
"es6-promise": "^4.1.0", | ||
@@ -67,3 +68,2 @@ "eslint": "^2.2.0", | ||
"http-server": "^0.9.0", | ||
"jquery": "^3.2.1", | ||
"json-loader": "^0.5.4", | ||
@@ -70,0 +70,0 @@ "karma": "^1.6.0", |
@@ -19,3 +19,4 @@ { | ||
"@atlaskit/dropdown-menu": "^1.1.0", | ||
"@atlassian/media-embed": "0.1.0-beta.7", | ||
"@atlaskit/media-card": "^17.1.1", | ||
"@atlaskit/media-core": "^8.0.0", | ||
"@atlassian/mediapicker": "^2.0.18", | ||
@@ -57,2 +58,3 @@ "axios": "^0.15.3", | ||
"redux-thunk": "^2.0.1", | ||
"rxjs": "^5.4.0", | ||
"sinon": "^2.1.0", | ||
@@ -59,0 +61,0 @@ "style-loader": "^0.13.0", |
@@ -11,2 +11,3 @@ /* CSS imports */ | ||
import {ContextFactory} from '@atlaskit/media-core'; | ||
@@ -58,2 +59,3 @@ /* Components */ | ||
let mpDropzone = null; | ||
let context = null; | ||
@@ -91,2 +93,13 @@ let setDropzoneActive = (active) => {}; | ||
mpDropzone.activate(); | ||
const {apiClientId, apiUrl, tokenSource} = mpConfig; | ||
context = ContextFactory.create({ | ||
clientId: apiClientId, | ||
serviceHost: apiUrl, | ||
tokenProvider: () => { | ||
return new Promise((resolve, reject) => { | ||
tokenSource.getter(reject, resolve); | ||
}); | ||
} | ||
}); | ||
} | ||
@@ -176,2 +189,3 @@ | ||
apiUrl={this.state.apiUrl} | ||
context={context} | ||
recentsCollection={RECENTS_COLLECTION} | ||
@@ -178,0 +192,0 @@ /> |
@@ -5,8 +5,6 @@ 'use strict'; | ||
import {isImage} from '../../../tools/isImage'; | ||
/* Components */ | ||
import {Dropzone} from './dropzone'; | ||
import * as MediaEmbed from '@atlassian/media-embed'; | ||
const MediaCard = MediaEmbed.Card; | ||
const FileProvider = MediaEmbed.MediaItemProvider; | ||
const MediaDataUriProvider = MediaEmbed.MediaDataUriProvider; | ||
import {Card, CardView} from '@atlaskit/media-card'; | ||
@@ -19,7 +17,2 @@ /* Actions */ | ||
/* Provider pool */ | ||
const mediaItemProviderPool= {}; | ||
let tokenProvider = () => Promise.resolve(''); | ||
let dataUriProvider = null; | ||
export class UploadView extends React.Component { | ||
@@ -40,34 +33,2 @@ constructor(props) { | ||
componentWillReceiveProps(nextProps) { | ||
const recentItems = nextProps.recents.items; | ||
recentItems.forEach((item) => { | ||
if (!mediaItemProviderPool[item.id]) { | ||
mediaItemProviderPool[item.id] = FileProvider.fromMediaApi( | ||
{ | ||
serviceHost: this.props.apiUrl, | ||
tokenProvider | ||
}, | ||
'file', | ||
item.id, | ||
this.props.client.id, | ||
this.props.recentsCollection | ||
); | ||
} | ||
}); | ||
tokenProvider = () => Promise.resolve(this.props.client.token); | ||
if (!dataUriProvider) { | ||
if (nextProps.apiUrl !== '') { | ||
dataUriProvider = new MediaDataUriProvider( | ||
nextProps.client.id, | ||
nextProps.apiUrl, | ||
tokenProvider, | ||
nextProps.recentsCollection | ||
); | ||
} | ||
} | ||
} | ||
render() { | ||
@@ -99,3 +60,3 @@ const cards = this._cards(); | ||
<div className="cards"> | ||
<div className="title">Recent Uploads</div> | ||
<div className="recentUploadsTitle">Recent Uploads</div> | ||
{cards} | ||
@@ -138,4 +99,19 @@ </div> | ||
_onFileClick(metadata, serviceName) { | ||
if (metadata) { | ||
const {id, mimeType, name, size} = metadata; | ||
this.props.dispatch( | ||
fileClick({ | ||
date: 0, | ||
id, | ||
mimeType, | ||
name, | ||
parentId: '', | ||
size | ||
}, serviceName, null) | ||
); | ||
} | ||
} | ||
_uploadingFilesCards() { | ||
const MediaCardView = MediaEmbed.MediaCardView; | ||
const itemsKeys = Object.keys(this.props.uploads); | ||
@@ -148,31 +124,24 @@ const selectedUploadIds = this.props.selectedItems | ||
const item = this.props.uploads[key]; | ||
const {progress, file} = item; | ||
const onClick = () => { | ||
this.props.dispatch(fileClick({ | ||
date: 0, | ||
id: item.file.metadata.id, | ||
mimeType: item.file.metadata.mimeType, | ||
name: item.file.metadata.name, | ||
parentId: "", | ||
size: item.file.metadata.size | ||
}, 'upload', null)); | ||
}; | ||
const mediaType = isImage(file.metadata.mimeType) ? 'image' : 'unknown'; | ||
const metadata = Object.assign({}, file.metadata, {mediaType}); | ||
const {id} = metadata; | ||
const selected = (selectedUploadIds.indexOf(id) > -1); | ||
const status = (progress !== null) ? 'uploading' : 'complete'; | ||
const onClick = () => this._onFileClick(metadata, 'upload'); | ||
const selected = (selectedUploadIds.indexOf(item.file.metadata.id) > -1); | ||
const mediaType = isImage(item.file.metadata.mimeType) ? 'image' : 'unknown'; | ||
return ( | ||
<div className="cardWrapper" key={item.file.metadata.id}> | ||
<MediaCardView | ||
dataURI={item.file.dataURI} | ||
mediaName={item.file.metadata.name} | ||
mediaSize={item.file.metadata.size} | ||
mediaType={mediaType} | ||
width={175} | ||
height={130} | ||
<div className="cardWrapper" key={id}> | ||
<CardView | ||
status={status} | ||
progress={progress} | ||
mediaItemType={'file'} | ||
metadata={metadata} | ||
dimensions={{width: 175, height: 130}} | ||
selectable={true} | ||
progress={item.progress} | ||
selected={selected} | ||
dataURI={file.dataURI} | ||
onClick={onClick} | ||
selected={selected} | ||
/> | ||
@@ -191,37 +160,29 @@ </div> | ||
const actions = [MediaEmbed.ActionCreators.CardClick((mediaItem) => { | ||
this.props.dispatch(fileClick({ | ||
date: 0, | ||
id: mediaItem.details.id, | ||
mimeType: mediaItem.details.mimeType, | ||
name: mediaItem.details.name, | ||
parentId: "", | ||
size: mediaItem.details.size | ||
}, 'recent_files', null)); | ||
})]; | ||
const onClick = (cardEvent) => { | ||
this._onFileClick(cardEvent.mediaItemDetails, 'recent_files'); | ||
}; | ||
return items.map((item) => { | ||
const selected = (selectedRecentFiles.indexOf(item.id) > -1); | ||
const {context, recentsCollection} = this.props; | ||
const {id, occurrenceKey} = item; | ||
const selected = (selectedRecentFiles.indexOf(id) > -1); | ||
const mediaItemProvider = mediaItemProviderPool[item.id]; | ||
return ( | ||
<div className="cardWrapper" key={`${item.occurrenceKey}-${item.id}`}> | ||
<MediaCard | ||
width={175} | ||
height={130} | ||
<div className="cardWrapper" key={`${occurrenceKey}-${id}`}> | ||
<Card | ||
context={context} | ||
identifier={{ | ||
mediaItemType: 'file', | ||
id: id, | ||
collectionName: recentsCollection | ||
}} | ||
dimensions={{width: 175, height: 130}} | ||
selectable={true} | ||
selected={selected} | ||
actions={actions} | ||
type={'file'} | ||
mediaItemProvider={mediaItemProvider} | ||
dataUriProvider={dataUriProvider} | ||
onClick={onClick} | ||
/> | ||
</div> | ||
) | ||
); | ||
}) | ||
} | ||
} |
import {MediaLocalUpload} from './localUpload'; | ||
import {ModuleConfig} from '../domain/config'; | ||
import {UploadParams} from '../domain/uploadParams'; | ||
import {MediaPickerContext} from '../domain/context'; | ||
@@ -11,4 +10,5 @@ | ||
public upload(base64: string, name: string = 'file'): void { | ||
const file = this._urltoFile(base64, name); | ||
public upload(base64: string, name: string): void { | ||
const filename = name || 'file'; | ||
const file = this._urltoFile(base64, filename); | ||
this._uploadService.addFile(file); | ||
@@ -29,4 +29,6 @@ } | ||
return new File([u8arr], filename, {type: mime}); | ||
const file = new Blob([u8arr], {type: mime}) as any; | ||
file.name = filename; | ||
return file; | ||
} | ||
} |
import '!style!css!less!./popup.less'; | ||
import * as $ from 'jquery'; | ||
import {UploadParams} from '../domain/uploadParams'; | ||
import {MediaLocalUpload} from './localUpload'; | ||
@@ -15,3 +13,3 @@ import {MPBrowserLoaded} from '../outer/analytics/events'; | ||
export class MediaPickerBrowser extends MediaLocalUpload { | ||
private _$browseElem: JQuery; | ||
private _browseElem: HTMLElement; | ||
@@ -21,8 +19,18 @@ constructor(context: MediaPickerContext, config: ModuleConfig, browserConfig: BrowserConfig = {}) { | ||
const multiple = (browserConfig.multiple) ? 'multiple' : ''; | ||
const accept = (browserConfig.fileExtensions) ? `accept="${browserConfig.fileExtensions.join(',')}"` : ''; | ||
this._$browseElem = $(`<input type="file" ${multiple} ${accept}>`); | ||
this._uploadService.addBrowse(this._$browseElem[0]); | ||
this._browseElem = document.createElement('INPUT'); | ||
this._browseElem.setAttribute('type', 'file'); | ||
if (browserConfig.multiple) { | ||
this._browseElem.setAttribute('multiple', ''); | ||
} | ||
if (browserConfig.fileExtensions) { | ||
this._browseElem.setAttribute('accept', browserConfig.fileExtensions.join(',')); | ||
} | ||
let div = document.createElement('DIV'); | ||
div.appendChild(this._browseElem); //IE11 hack - click will not execute if input has no parent | ||
this._uploadService.addBrowse(this._browseElem); | ||
this._context.trackEvent(new MPBrowserLoaded()); | ||
@@ -32,4 +40,4 @@ } | ||
public browse(): void { | ||
this._$browseElem.click(); | ||
this._browseElem.click(); | ||
} | ||
} |
@@ -1,3 +0,1 @@ | ||
import * as $ from 'jquery'; | ||
import {UploadParams} from '../domain/uploadParams'; | ||
import {MediaLocalUpload} from './localUpload'; | ||
@@ -7,8 +5,18 @@ import {MPClipboardLoaded} from '../outer/analytics/events'; | ||
import {ModuleConfig} from '../domain/config'; | ||
import {MutatedFile} from '../util/typeExtensions'; | ||
import {JQueryBound} from './component'; | ||
import domready = require('domready'); | ||
export class MediaPickerClipboard extends MediaLocalUpload { | ||
private _bound: {paste: JQueryBound}; | ||
private _pasteHandler = (event: ClipboardEvent): void => { | ||
const clipboardData = this._getClipboardData(event); | ||
if (!clipboardData) { | ||
return; | ||
} | ||
const dataTransferItem = clipboardData.items && clipboardData.items[0]; | ||
if (dataTransferItem && dataTransferItem.kind === 'file') { | ||
const file = dataTransferItem.getAsFile(); | ||
this._uploadService.addFile(file); | ||
} | ||
}; | ||
constructor(context: MediaPickerContext, config: ModuleConfig) { | ||
@@ -20,10 +28,5 @@ super(context, config); | ||
public activate(): void { | ||
$(document).ready(() => { | ||
domready(() => { | ||
this.deactivate(); | ||
this._bound = { | ||
'paste': this._onFilesPasted.bind(this) | ||
}; | ||
$(document).on(this._bound); | ||
document.addEventListener('paste', this._pasteHandler, false); | ||
}); | ||
@@ -33,29 +36,8 @@ } | ||
public deactivate(): void { | ||
$(document).off(this._bound); | ||
document.removeEventListener('paste', this._pasteHandler); | ||
} | ||
private _onFilesPasted(event: ClipboardEvent | BaseJQueryEventObject): void { | ||
const clipboardData = this._getClipboardData(event); | ||
if (!clipboardData) { | ||
return; | ||
} | ||
const dataTransferItem = clipboardData.items && clipboardData.items[0]; | ||
if (dataTransferItem && dataTransferItem.kind === 'file') { | ||
const file = dataTransferItem.getAsFile(); | ||
(file as MutatedFile).lastModified = Date.now(); | ||
(file as MutatedFile).name = 'Untitled'; | ||
this._uploadService.addFile(file); | ||
} | ||
private _getClipboardData(event: ClipboardEvent): DataTransfer | null { | ||
return event ? event.clipboardData : null; | ||
} | ||
private _getClipboardData(event: ClipboardEvent | BaseJQueryEventObject): DataTransfer | null { | ||
const originalEvent = (event as BaseJQueryEventObject).originalEvent as ClipboardEvent; | ||
if (originalEvent) { | ||
return originalEvent.clipboardData; | ||
} else { | ||
const clipboardEvent = (event as ClipboardEvent); | ||
return clipboardEvent ? clipboardEvent.clipboardData : null; | ||
} | ||
} | ||
} |
import {MediaPickerContext} from '../domain/context'; | ||
const appConfig = require('!json!../config.json'); | ||
import * as $ from 'jquery'; | ||
import { EventEmitter } from 'events'; | ||
import {EventEmitter} from 'events'; | ||
import { UploadService, FileFinalize } from '../service/uploadService'; | ||
import { MediaFile } from '../domain/file'; | ||
import { MediaProgress } from '../domain/progress'; | ||
import { handleError } from '../util/handleError'; | ||
import { MediaError } from '../domain/error'; | ||
import {FileFinalize} from '../service/uploadService'; | ||
import {MediaFile} from '../domain/file'; | ||
import {MediaProgress} from '../domain/progress'; | ||
import {handleError} from '../util/handleError'; | ||
import {MediaError} from '../domain/error'; | ||
@@ -16,4 +15,2 @@ import { MPFileUploadStarted, MPFileProcessingStarted, MPFileUploadEnded } from '../outer/analytics/events'; | ||
export type JQueryBound = (eventObject: JQueryEventObject, ...args: any[]) => any; | ||
export const EVENT_NAMES = { | ||
@@ -20,0 +17,0 @@ UPLOAD_START: 'upload-start', |
import {expect} from 'chai'; | ||
import * as $ from 'jquery'; | ||
import {MediaPicker} from '../index'; | ||
@@ -15,3 +14,4 @@ import {ModuleConfig} from '../domain/config'; | ||
it('constructor returns the Dropzone object', () => { | ||
const pickerObj = MediaPicker('dropzone', apiConfig, {container: $('<div></div>')}); | ||
const container = document.createElement('DIV'); | ||
const pickerObj = MediaPicker('dropzone', apiConfig, {container}); | ||
expect(pickerObj).to.be.instanceOf(MediaPickerDropzone); | ||
@@ -21,9 +21,8 @@ }); | ||
it('injects into container correctly', (done) => { | ||
const $container = $('<div></div>'); | ||
const dropzone = MediaPicker('dropzone', apiConfig, {container: $container}); | ||
const container = document.createElement('DIV'); | ||
const dropzone = MediaPicker('dropzone', apiConfig, {container}); | ||
dropzone.activate(); | ||
window.setTimeout(() => { // FIXME FIL-1962 replace setTimeout to callback in tests | ||
expect($container.find('.mediaPickerDropzone').length).to.be.equal(1); | ||
window.setTimeout(() => { // FIXME FIL-1962 replace setTimeout to callback in tests | ||
expect(container.querySelectorAll('.mediaPickerDropzone').length).to.be.equal(1); | ||
done(); | ||
@@ -38,3 +37,3 @@ }, 1500); | ||
window.setTimeout(() => { | ||
expect($('body').find('.mediaPickerDropzone').length === 1).to.be.equal(true); | ||
expect(document.body.querySelectorAll('.mediaPickerDropzone').length).to.be.equal(1); | ||
done(); | ||
@@ -48,30 +47,25 @@ }, 1500); | ||
it('Dragover shows Dropzone, Dragleave hides it', (done) => { | ||
const dragOver = { | ||
type: 'dragover', | ||
preventDefault: () => { | ||
}, | ||
originalEvent: { | ||
dataTransfer: { | ||
types: ['Files'], | ||
effectAllowed: 'move' | ||
} | ||
} | ||
const dragOver = document.createEvent('Event') as any; | ||
dragOver.initEvent('dragover', true, true); | ||
dragOver.preventDefault = () => {}; | ||
dragOver.dataTransfer = { | ||
types: ['Files'], | ||
effectAllowed: 'move' | ||
}; | ||
const dragLeave = { | ||
type: 'dragleave', | ||
preventDefault: () => { | ||
}, | ||
}; | ||
const $container = $('<div></div>'); | ||
const dropzone = MediaPicker('dropzone', apiConfig, {container: $container}); | ||
const dragLeave = document.createEvent('Event') as any; | ||
dragLeave.initEvent('dragleave', true, true); | ||
dragLeave.preventDefault = () => {}; | ||
const container = document.createElement('DIV'); | ||
const dropzone = MediaPicker('dropzone', apiConfig, {container}); | ||
dropzone.activate(); | ||
window.setTimeout(() => { | ||
expect($container.find('.mediaPickerDropzone').hasClass("active")).to.be.equal(false); | ||
$container.trigger(<any>dragOver); | ||
expect($container.find('.mediaPickerDropzone').hasClass("active")).to.be.equal(true); | ||
$container.trigger(<any>dragLeave); | ||
expect($container.find('.mediaPickerDropzone').hasClass("active")).to.be.equal(false); | ||
expect(container.querySelector('.mediaPickerDropzone').className.indexOf('active') > -1).to.be.false; | ||
container.dispatchEvent(dragOver); | ||
expect(container.querySelector('.mediaPickerDropzone').className.indexOf('active') > -1).to.be.true; | ||
container.dispatchEvent(dragLeave); | ||
expect(container.querySelector('.mediaPickerDropzone').className.indexOf('active') > -1).to.be.false; | ||
done(); | ||
@@ -78,0 +72,0 @@ }, 1500); |
import '!style!css!less!./dropzone.less'; | ||
import * as $ from 'jquery'; | ||
import {UploadParams} from '../domain/uploadParams'; | ||
import axios from 'axios'; | ||
import {MediaLocalUpload} from './localUpload'; | ||
@@ -9,6 +8,7 @@ import {handleError} from '../util/handleError'; | ||
import {ModuleConfig} from '../domain/config'; | ||
import {JQueryBound} from './component'; | ||
import {parseHTML} from '../util/parseHTML'; | ||
import domready = require('domready'); | ||
export interface DropzoneConfig { | ||
container?: JQuery; | ||
container?: HTMLElement; | ||
headless?: boolean; | ||
@@ -18,13 +18,32 @@ } | ||
export class MediaPickerDropzone extends MediaLocalUpload { | ||
private _$container: JQuery; | ||
private _$instance: JQuery; | ||
private _binded: { | ||
'dragover': JQueryBound, | ||
'dragleave': JQueryBound | ||
}; | ||
private _container: HTMLElement; | ||
private _instance: HTMLElement; | ||
private _headless: boolean; | ||
private _uiActive: boolean; | ||
private _onDragOver = (e: DragEvent): void => { | ||
e.preventDefault(); | ||
private static _dragContainsFiles(e: BaseJQueryEventObject): boolean { | ||
const event = e.originalEvent as DragEvent; | ||
if (MediaPickerDropzone._dragContainsFiles(e)) { | ||
const dataTransfer = e.dataTransfer; | ||
if (dataTransfer) { | ||
let allowed; | ||
try { | ||
const allowed = dataTransfer.effectAllowed; | ||
} catch (e) {} // the error is expected in IE11 | ||
dataTransfer.dropEffect = ('move' === allowed || 'linkMove' === allowed) ? 'move' : 'copy'; | ||
this._instance.classList.add('active'); | ||
this.emitDragOver(); | ||
} | ||
} | ||
}; | ||
private _onDragLeave = (e: DragEvent): void => { | ||
e.preventDefault(); | ||
this._instance.classList.remove('active'); | ||
this.emitDragLeave(); | ||
}; | ||
private static _dragContainsFiles(event: DragEvent): boolean { | ||
const types = []; | ||
@@ -42,3 +61,3 @@ | ||
const dzConfig = dropzoneConfig; | ||
this._$container = $(dzConfig.container || 'body'); | ||
this._container = dzConfig.container; | ||
this._headless = dzConfig.headless || false; | ||
@@ -51,8 +70,6 @@ this._uiActive = false; | ||
public activate(): void { | ||
$(document).ready(() => { | ||
if (this._$container.length === 0) { | ||
this._$container = $(this._$container.selector); //reloading jquery selector each time dropzone is activated | ||
} | ||
domready(() => { | ||
this._container = this._container || document.body; | ||
if (typeof this._$instance === 'undefined') { | ||
if (!this._instance) { | ||
this._createInstance(); | ||
@@ -63,8 +80,4 @@ } | ||
this._binded = { | ||
'dragover': this._onDragOver.bind(this), | ||
'dragleave': this._onDragLeave.bind(this) | ||
}; | ||
$(this._$container).on(this._binded); | ||
this._container.addEventListener('dragover', this._onDragOver, false); | ||
this._container.addEventListener('dragleave', this._onDragLeave, false); | ||
}); | ||
@@ -74,14 +87,15 @@ } | ||
public deactivate(): void { | ||
$(this._$container).off(this._binded); | ||
this._container.removeEventListener('dragover', this._onDragOver, false); | ||
this._container.removeEventListener('dragleave', this._onDragLeave, false); | ||
} | ||
private _createInstance(): Promise<JQuery> { | ||
return new Promise<JQuery>((resolve) => { | ||
private _createInstance(): Promise<HTMLElement> { | ||
return new Promise((resolve) => { | ||
return this._getDropzoneUI() | ||
.then(($element) => { | ||
this._$instance = $element; | ||
$(this._$container).append(this._$instance); | ||
.then((element) => { | ||
this._instance = element; | ||
this._container.appendChild(this._instance); | ||
this._uploadService.on('file-dropped', this._onDrop.bind(this)); | ||
this._uploadService.addDropzone(this._$container[0]); | ||
resolve(this._$instance); | ||
this._uploadService.addDropzone(this._container); | ||
resolve(this._instance); | ||
} | ||
@@ -92,13 +106,13 @@ ); | ||
private _getDropzoneUI(): Promise<JQuery> { | ||
private _getDropzoneUI(): Promise<HTMLElement> { | ||
if (this._headless) { | ||
return Promise.resolve($('<div></div>')); | ||
return Promise.resolve(document.createElement('DIV')); | ||
} else { | ||
return new Promise<JQuery>((resolve) => { | ||
return $.ajax({url: this.getStaticAssetUrl('dropzone')}) | ||
.done((data) => { | ||
resolve($($.parseHTML(data))); | ||
}) | ||
.fail((jqXHR) => { | ||
handleError('dropzone_load_fail', jqXHR.statusCode().status); | ||
return new Promise((resolve) => { | ||
return axios.get(this.getStaticAssetUrl('dropzone')).then( | ||
(response) => { | ||
resolve(parseHTML(response.data)); | ||
}, | ||
(error) => { | ||
handleError('dropzone_load_fail', error); | ||
}); | ||
@@ -109,30 +123,6 @@ }); | ||
private _onDragOver(e: BaseJQueryEventObject): void { | ||
e.preventDefault(); | ||
private _onDrop(e: DragEvent): void { | ||
if (MediaPickerDropzone._dragContainsFiles(e)) { | ||
if (e.originalEvent && (e.originalEvent as DragEvent).dataTransfer) { | ||
try { | ||
const dataTransfer = (e.originalEvent as DragEvent).dataTransfer; | ||
const allowed = dataTransfer.effectAllowed; | ||
dataTransfer.dropEffect = ('move' === allowed || 'linkMove' === allowed) ? 'move' : 'copy'; | ||
$(this._$instance).addClass('active'); | ||
this.emitDragOver(); | ||
} catch (e) { | ||
// noop | ||
} | ||
} | ||
} | ||
} | ||
private _onDragLeave(e: BaseJQueryEventObject): void { | ||
e.preventDefault(); | ||
$(this._$instance).removeClass('active'); | ||
this.emitDragLeave(); | ||
} | ||
private _onDrop(e: BaseJQueryEventObject): void { | ||
if (MediaPickerDropzone._dragContainsFiles(e)) { | ||
$(this._$container).removeClass('mediaPickerDropzoneActive'); | ||
$(this._$instance).removeClass('active'); | ||
this._instance.classList.remove('mediaPickerDropzoneActive'); | ||
this._instance.classList.remove('active'); | ||
this.emit('drop'); | ||
@@ -139,0 +129,0 @@ this.emitDragLeave(); |
import {MediaAPI} from '../service/mediaAPI'; | ||
import '!style!css!less!./popup.less'; | ||
import * as $ from 'jquery'; | ||
import * as uuid from 'uuid'; | ||
@@ -22,6 +21,7 @@ import {MPComponent} from './component'; | ||
import {MediaApiData} from '../service/mediaAPI'; | ||
import {ClGetterSuccessCb, ClGetterFailCb} from '../domain/config'; | ||
import {PopupUrls} from '../interactors/popupInteraction'; | ||
import {convertBase64ToBlob} from '../util/convertBase64ToBlob'; | ||
import {EVENT_NAMES} from './component'; | ||
import domready = require('domready'); | ||
import {parseHTML} from '../util/parseHTML'; | ||
@@ -33,3 +33,3 @@ interface UploadsMap { | ||
export interface PopupConfig { | ||
container?: JQuery; | ||
container?: HTMLElement; | ||
} | ||
@@ -40,5 +40,5 @@ | ||
export class MediaPickerPopup extends MPComponent { | ||
private _$container: JQuery; | ||
private _$instance: JQuery; | ||
private _$userMethodsHelper: JQuery; | ||
private _container: HTMLElement; | ||
private _instance: HTMLElement; | ||
private _userMethodsHelper: HTMLIFrameElement; | ||
private _config: ModuleConfig; | ||
@@ -53,48 +53,51 @@ private _tenantAPIClient: MediaAPI; | ||
super(context); | ||
this._context = context; | ||
if (popupConfig && popupConfig.container) { | ||
this._$container = popupConfig.container; | ||
} else { | ||
this._$container = $('body'); | ||
} | ||
this._context.trackEvent(new MPPopupLoaded()); | ||
this._config = config; | ||
this._uploadParams = config.uploadParams || {}; | ||
this._uploads = {}; | ||
domready(() => { | ||
if (popupConfig && popupConfig.container) { | ||
this._container = popupConfig.container; | ||
} else { | ||
this._container = document.body; | ||
} | ||
this._context.trackEvent(new MPPopupLoaded()); | ||
this._config = config; | ||
this._uploadParams = config.uploadParams || {}; | ||
this._uploads = {}; | ||
this.init(); | ||
}) | ||
} | ||
public init(): void { | ||
/* userMethods iframe */ | ||
const channelName = uuid.v4(); | ||
this._$userMethodsHelper = $(`<iframe src="${this.getStaticAssetUrl('userMethodsHelperUrl')}?channelName=${channelName}"></iframe>`); | ||
this._$userMethodsHelper.hide(); | ||
$(this._$container).append(this._$userMethodsHelper); | ||
const iframeWindow = (this._$userMethodsHelper.get()[0] as HTMLIFrameElement).contentWindow; | ||
this._userMethodsInteractor = new UserMethodsInteractor( | ||
this._$container, | ||
iframeWindow, | ||
channelName, | ||
this._config.apiUrl); | ||
this._userMethodsHelper = document.createElement('IFRAME') as HTMLIFrameElement; | ||
this._userMethodsHelper.setAttribute('src', `${this.getStaticAssetUrl('userMethodsHelperUrl')}?channelName=${channelName}`); | ||
this._userMethodsHelper.style.display = 'none'; | ||
this._container.appendChild(this._userMethodsHelper); | ||
$(document).ready(() => { | ||
this._$instance = this._createInstance(); | ||
$(this._$container).append(this._$instance); | ||
this._initProtocols(); | ||
}) | ||
const iframeWindow = this._userMethodsHelper.contentWindow; | ||
this._userMethodsInteractor = new UserMethodsInteractor(iframeWindow, channelName, this._config.apiUrl); | ||
/* popup iframe */ | ||
this._instance = this._createInstance(); | ||
this._container.appendChild(this._instance); | ||
return this._initProtocols(); | ||
} | ||
public show(): Promise<JQuery> { | ||
return new Promise<JQuery>((resolve, reject) => { | ||
this._tenantAPIClient.setUploadParams(this._uploadParams) | ||
.then(() => { | ||
this._popupIframe.resetView(); | ||
this._show(resolve); | ||
}, | ||
(err) => { | ||
this.emitUploadError(err); | ||
} | ||
); | ||
}); | ||
public show(): Promise<undefined> { | ||
if (!this._instance || !this._userMethodsHelper) { | ||
this.init(); | ||
} | ||
return this._tenantAPIClient.setUploadParams(this._uploadParams) | ||
.then(() => { | ||
this._popupIframe.resetView(); | ||
this._show(); | ||
}, | ||
(err) => { | ||
this.emitUploadError(err); | ||
} | ||
); | ||
} | ||
@@ -108,4 +111,11 @@ | ||
public teardown(): void { | ||
this._$instance.remove(); | ||
this._$userMethodsHelper.remove(); | ||
if (this._instance) { | ||
this._instance.parentNode.removeChild(this._instance); | ||
delete this._instance; | ||
} | ||
if (this._userMethodsHelper) { | ||
this._userMethodsHelper.parentNode.removeChild(this._userMethodsHelper); | ||
delete this._userMethodsHelper; | ||
} | ||
} | ||
@@ -138,5 +148,4 @@ | ||
private _show(resolve: (instance: JQuery) => void): void { | ||
this._$instance.show(); | ||
resolve(this._$instance); | ||
private _show(): void { | ||
this._instance.style.display = 'block'; | ||
this._context.trackEvent(new MPPopupShown()); | ||
@@ -146,3 +155,5 @@ } | ||
public hide(): void { | ||
this._$instance && this._$instance.hide(); | ||
if (this._instance) { | ||
this._instance.style.display = 'none'; | ||
} | ||
this._context.trackEvent(new MPPopupHidden()); | ||
@@ -155,5 +166,4 @@ } | ||
private _createInstance(): JQuery { | ||
const $instance = $(` | ||
<div class="mediaPickerPopup mpAUI"> | ||
private _createInstance(): HTMLElement { | ||
return parseHTML(`<div class="mediaPickerPopup mpAUI"> | ||
<section role="dialog" id="demo-dialog" class="aui-layer aui-dialog2 aui-dialog2-large" aria-hidden="false"> | ||
@@ -164,16 +174,12 @@ <div class="aui-dialog2-content"> | ||
</section> | ||
</div> | ||
`); | ||
return $instance; | ||
</div>`); | ||
} | ||
private _createInteractionLayer(urls: PopupUrls): InteractionLayer { | ||
const $popupIframe = $('.mpApp', this._$instance); | ||
const popupIframe = this._instance.querySelector('.mpApp') as HTMLIFrameElement; | ||
const channelName = uuid.v4(); | ||
const iframeSrc = `${$popupIframe.attr('src')}?channelName=${channelName}`; | ||
$popupIframe.attr('src', iframeSrc); | ||
const targetWindow = ($popupIframe.get()[0] as HTMLIFrameElement).contentWindow; | ||
const iframeSrc = `${popupIframe.getAttribute('src')}?channelName=${channelName}`; | ||
popupIframe.setAttribute('src', iframeSrc); | ||
const targetWindow = popupIframe.contentWindow; | ||
const popup = new InteractionLayer(this, targetWindow, channelName, urls); | ||
popup.on('fetchFile', (file: any) => { | ||
@@ -180,0 +186,0 @@ if (file.serviceName === 'recent_files') { |
@@ -1,2 +0,1 @@ | ||
import * as JQuery from 'jquery'; | ||
import {Postis, PostisChannel} from 'postis'; | ||
@@ -54,4 +53,3 @@ import * as postis from 'postis'; | ||
constructor(private _$container: JQuery, | ||
private _targetWindow: Window, | ||
constructor(private _targetWindow: Window, | ||
private _channelName: string, | ||
@@ -58,0 +56,0 @@ private _apiUrl: string) { |
import axios from 'axios'; | ||
import * as $ from 'jquery'; | ||
import {EventEmitter} from 'events'; | ||
@@ -95,3 +94,3 @@ import * as url from 'url'; | ||
public setUploadParams(uploadParams: UploadParams): Promise<void> { | ||
public setUploadParams(uploadParams: UploadParams): Promise<undefined> { | ||
this._uploadParams = uploadParams; | ||
@@ -163,6 +162,6 @@ | ||
return new Promise((resolve, reject) => { | ||
$.get(url).then( | ||
(data) => { | ||
if (data.data.processingStatus === 'succeeded' || data.data.processingStatus === 'failed') { | ||
resolve(data.data); | ||
axios.get(url).then( | ||
(response) => { | ||
if (response.data.data.processingStatus === 'succeeded' || response.data.data.processingStatus === 'failed') { | ||
resolve(response.data.data); | ||
} else { | ||
@@ -260,3 +259,3 @@ setTimeout(() => { | ||
private _handleUploadError(errName: string, errDetails?: string, uploadId?: string): Promise<{}> { | ||
private _handleUploadError(errName: string, errDetails?: string, uploadId?: string): Promise<undefined> { | ||
return new Promise((resolve, reject) => { | ||
@@ -263,0 +262,0 @@ this.emit('upload-error', new MediaError(uploadId, errName, errDetails)); |
import {TokenSource} from '../domain/config'; | ||
import * as $ from 'jquery'; | ||
import {Rusha} from 'rusha'; | ||
@@ -18,3 +17,2 @@ import {EventEmitter} from 'events'; | ||
type QueryParams = {[name: string]: string | number | boolean}; | ||
type UploadId = string; | ||
@@ -50,3 +48,3 @@ type ChunkId = string; | ||
collection?: string; | ||
}; | ||
} | ||
@@ -62,3 +60,2 @@ export class UploadService extends EventEmitter { | ||
private _resumable: Resumable; | ||
private _$nativeForm: JQuery; | ||
@@ -68,2 +65,4 @@ private _hashGenerator: Function; | ||
private _dropListener: EventListener; | ||
constructor(private _url: string, | ||
@@ -127,8 +126,2 @@ private _clientId: string, | ||
this._resumable.on('fileError', (fileObj, err) => this._onFileError(fileObj, err)); | ||
// create a detached native browse button and form | ||
this._$nativeForm = $('<form action="/" method="post" enctype="multipart/form-data"><input type="file"/></form>'); | ||
const $nativeFileButton = this._$nativeForm.find('input'); | ||
$nativeFileButton.change((ev) => $('form').submit()); | ||
$nativeFileButton.click((ev) => ev.stopPropagation()); | ||
} | ||
@@ -150,25 +143,21 @@ | ||
addBrowse(element: HTMLElement): void { | ||
if (!this._resumable.support || !supportsModernUploader()) { | ||
$(element).on('click', (ev) => { | ||
ev.preventDefault(); | ||
this._$nativeForm.find('input').click(); | ||
}); | ||
} else { | ||
this._resumable.assignBrowse(element); | ||
} | ||
this._resumable.assignBrowse(element); | ||
} | ||
addDropzone(element: HTMLElement): void { | ||
if (this._resumable.support && supportsModernUploader()) { | ||
$(element).on('drop.hm-uploader', (ev) => { | ||
const dataTransfer = ev.originalEvent && (ev.originalEvent as DragEvent).dataTransfer; | ||
if (dataTransfer && dataTransfer.files.length) { | ||
ev.preventDefault(); | ||
ev.stopPropagation(); | ||
this.emit('file-dropped', ev); | ||
} | ||
}); | ||
if(this._dropListener) { | ||
return; // component can have only one active dropzone | ||
} | ||
this._resumable.assignDrop(element); | ||
} | ||
this._dropListener = (ev: DragEvent) => { | ||
const dataTransfer = ev.dataTransfer; | ||
if (dataTransfer && dataTransfer.files.length) { | ||
ev.preventDefault(); | ||
ev.stopPropagation(); | ||
this.emit('file-dropped', ev); | ||
} | ||
}; | ||
element.addEventListener('drop', this._dropListener); | ||
this._resumable.assignDrop(element); | ||
} | ||
@@ -192,6 +181,4 @@ | ||
removeDropzone(element: HTMLElement): void { | ||
if (this._resumable.support && supportsModernUploader()) { | ||
$(element).off('drop.hm-uploader'); | ||
this._resumable.unAssignDrop(element); | ||
} | ||
element.removeEventListener('drop', this._dropListener); | ||
this._resumable.unAssignDrop(element); | ||
} | ||
@@ -283,12 +270,12 @@ | ||
private _pollFile(fileId: string, collection: string, cb: Function): void { | ||
private _pollFile(fileId: string, collection: string, callback: Function): void { | ||
const collectionName = (collection) ? `&collection=${collection}` : ''; | ||
const url = `${this._url}/file/${fileId}?client=${this._clientId}&token=${this._token}${collectionName}`; | ||
$.get(url).then( | ||
(data) => { | ||
if (data.data.processingStatus === 'succeeded') { | ||
cb(data.data); | ||
axios.get(url).then( | ||
(response) => { | ||
if (response.data.data.processingStatus === 'succeeded' || response.data.data.processingStatus === 'failed') { | ||
callback(response.data.data); | ||
} else { | ||
setTimeout(() => { | ||
this._pollFile.call(this, fileId, collection, cb); | ||
this._pollFile.call(this, fileId, collection, callback); | ||
}, 2000); | ||
@@ -386,3 +373,3 @@ } | ||
_handleUploadError(errName: string, errDetails?: string, uploadId?: string): Promise<{}> { | ||
_handleUploadError(errName: string, errDetails?: string, uploadId?: string): Promise<undefined> { | ||
return new Promise((resolve, reject) => { | ||
@@ -389,0 +376,0 @@ //retry in case token expired |
import {TokenSource} from '../domain/config'; | ||
import {ERROR_NAMES} from '../domain/error'; | ||
import * as $ from 'jquery'; | ||
import axios, {AxiosError, AxiosResponse} from 'axios'; | ||
@@ -21,14 +21,8 @@ export function getTokenFromSource(tokenSource: TokenSource): Promise<string> { | ||
function fetchTokenFromUrl(url: string): Promise<string> { | ||
return new Promise((resolve, reject) => { | ||
return $.post(url).then((parsedBody, statusText, xhr) => { | ||
if ((xhr.status !== 201) && (xhr.status !== 200)) { | ||
reject(ERROR_NAMES.TOKEN_FETCH_FAIL); | ||
} | ||
resolve(parsedBody.token); | ||
}).fail(ignored => { | ||
reject(ERROR_NAMES.TOKEN_FETCH_FAIL); | ||
}); | ||
return (axios.post(url) as Promise<AxiosResponse>).then((response: AxiosResponse) => { | ||
return response.data.token; | ||
},(ignored: AxiosError) => { | ||
return ERROR_NAMES.TOKEN_FETCH_FAIL; | ||
}); | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
254
71077
9560850