mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
Merge branch 'development' into dev-denys-dts
# Conflicts: # demo-shell-ng2/systemjs.config.js # ng2-components/ng2-alfresco-upload/src/services/upload.service.spec.ts # ng2-components/ng2-alfresco-upload/src/services/upload.service.ts # ng2-components/ng2-alfresco-viewer/src/componets/viewer.component.spec.t s # ng2-components/ng2-alfresco-viewer/src/componets/viewer.component.ts
This commit is contained in:
@@ -146,7 +146,6 @@ Attribute | Options | Default | Description | Mandatory
|
||||
`showViewer` | *boolean* | `true` | Hide or show the viewer |
|
||||
`showToolbar` | *boolean* | `true` | Hide or show the toolbars |
|
||||
|
||||
|
||||
## Build from sources
|
||||
Alternatively you can build component from sources with the following commands:
|
||||
|
||||
|
@@ -38,7 +38,7 @@
|
||||
"material-design-lite": "1.1.3",
|
||||
"pdfjs-dist": "1.5.258",
|
||||
|
||||
"ng2-alfresco-core": "^0.2.0",
|
||||
"ng2-alfresco-core": "^0.3.0",
|
||||
"ng2-translate": "2.2.2",
|
||||
"alfresco-js-api": "^0.3.0",
|
||||
"ng2-alfresco-viewer" : "file:../"
|
||||
|
@@ -17,9 +17,7 @@
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||
import { VIEWERCOMPONENT } from 'ng2-alfresco-viewer';
|
||||
|
||||
import { HTTP_PROVIDERS } from '@angular/http';
|
||||
import { VIEWERCOMPONENT, RenderingQueueServices } from 'ng2-alfresco-viewer';
|
||||
|
||||
import {
|
||||
ALFRESCO_CORE_PROVIDERS,
|
||||
@@ -30,12 +28,12 @@ import {
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
template: `
|
||||
<label for="token"><b>Insert a valid access token / ticket:</b></label><br>
|
||||
<input id="token" type="text" size="48" (change)="updateToken();documentList.reload()" [(ngModel)]="token"><br>
|
||||
<label for="token"><b>Insert the ip of your Alfresco instance:</b></label><br>
|
||||
<input id="token" type="text" size="48" (change)="updateHost();documentList.reload()" [(ngModel)]="ecmHost"><br><br>
|
||||
<label for="ticket"><b>Insert a valid access ticket / ticket:</b></label><br>
|
||||
<input id="ticket" type="text" size="48" (change)="updateTicket()" [(ngModel)]="ticket"><br>
|
||||
<label for="host"><b>Insert the ip of your Alfresco instance:</b></label><br>
|
||||
<input id="host" type="text" size="48" (change)="updateHost()" [(ngModel)]="ecmHost"><br><br>
|
||||
<div *ngIf="!authenticated" style="color:#FF2323">
|
||||
Authentication failed to ip {{ ecmHost }} with user: admin, admin, you can still try to add a valid token to perform
|
||||
Authentication failed to ip {{ ecmHost }} with user: admin, admin, you can still try to add a valid ticket to perform
|
||||
operations.
|
||||
</div>
|
||||
<hr>
|
||||
@@ -54,19 +52,20 @@ class MyDemoApp {
|
||||
|
||||
ecmHost: string = 'http://127.0.0.1:8080';
|
||||
|
||||
token: string;
|
||||
ticket: string;
|
||||
|
||||
constructor(private authService: AlfrescoAuthenticationService,
|
||||
private settingsService: AlfrescoSettingsService) {
|
||||
|
||||
settingsService.ecmHost = this.ecmHost;
|
||||
if (this.authService.getTicket()) {
|
||||
this.token = this.authService.getTicket();
|
||||
settingsService.setProviders('ECM');
|
||||
|
||||
if (this.authService.getTicketEcm()) {
|
||||
this.ticket = this.authService.getTicketEcm();
|
||||
}
|
||||
}
|
||||
|
||||
public updateToken(): void {
|
||||
localStorage.setItem('token', this.token);
|
||||
public updateTicket(): void {
|
||||
localStorage.setItem('ticket-ECM', this.ticket);
|
||||
}
|
||||
|
||||
public updateHost(): void {
|
||||
@@ -80,9 +79,9 @@ class MyDemoApp {
|
||||
|
||||
login() {
|
||||
this.authService.login('admin', 'admin').subscribe(
|
||||
token => {
|
||||
console.log(token);
|
||||
this.token = token;
|
||||
ticket => {
|
||||
console.log(ticket);
|
||||
this.ticket = this.authService.getTicketEcm();
|
||||
this.authenticated = true;
|
||||
},
|
||||
error => {
|
||||
@@ -93,6 +92,6 @@ class MyDemoApp {
|
||||
}
|
||||
bootstrap(MyDemoApp, [
|
||||
VIEWERCOMPONENT,
|
||||
HTTP_PROVIDERS,
|
||||
ALFRESCO_CORE_PROVIDERS
|
||||
ALFRESCO_CORE_PROVIDERS,
|
||||
RenderingQueueServices
|
||||
]);
|
||||
|
@@ -15,7 +15,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ViewerComponent } from './src/viewer.component';
|
||||
import { ViewerComponent } from './src/componets/viewer.component';
|
||||
import { RenderingQueueServices } from './src/services/rendering-queue.services';
|
||||
|
||||
/**
|
||||
* ng2-alfresco-viewer, provide components to view files.
|
||||
@@ -26,12 +27,18 @@ import { ViewerComponent } from './src/viewer.component';
|
||||
* </alfresco-viewer>
|
||||
*/
|
||||
|
||||
export * from './src/viewer.component';
|
||||
export * from './src/componets/viewer.component';
|
||||
export * from './src/services/rendering-queue.services';
|
||||
|
||||
export default {
|
||||
components: [ViewerComponent]
|
||||
components: [ViewerComponent],
|
||||
directives: [RenderingQueueServices]
|
||||
};
|
||||
|
||||
export const VIEWERCOMPONENT: [any] = [
|
||||
ViewerComponent
|
||||
];
|
||||
|
||||
export const ALFRESCO_VIEWER_SERVICES: [any] = [
|
||||
RenderingQueueServices
|
||||
];
|
||||
|
@@ -5,7 +5,7 @@ module.exports = function (config) {
|
||||
|
||||
basePath: '.',
|
||||
|
||||
frameworks: ['jasmine'],
|
||||
frameworks: ['jasmine-ajax', 'jasmine'],
|
||||
|
||||
files: [
|
||||
// paths loaded by Karma
|
||||
@@ -19,7 +19,9 @@ module.exports = function (config) {
|
||||
{pattern: 'node_modules/ng2-alfresco-core/dist/**/*.js', included: false, served: true, watched: false},
|
||||
{pattern: 'node_modules/ng2-translate/**/*.js', included: false, served: true, watched: false},
|
||||
{pattern: 'node_modules/alfresco-js-api/dist/alfresco-js-api.js', included: true, watched: false},
|
||||
|
||||
{pattern: 'node_modules/pdfjs-dist/build/pdf.js', included: true, watched: false},
|
||||
{pattern: 'node_modules/pdfjs-dist/build/pdf.worker.js', included: true, watched: false},
|
||||
{pattern: 'node_modules/pdfjs-dist/web/pdf_viewer.js', included: true, watched: false},
|
||||
{pattern: 'karma-test-shim.js', included: true, watched: true},
|
||||
|
||||
// paths loaded via module imports
|
||||
@@ -29,7 +31,9 @@ module.exports = function (config) {
|
||||
|
||||
// paths to support debugging with source maps in dev tools
|
||||
{pattern: 'src/**/*.ts', included: false, watched: false},
|
||||
{pattern: 'dist/**/*.js.map', included: false, watched: false}
|
||||
{pattern: 'dist/**/*.js.map', included: false, watched: false},
|
||||
|
||||
{pattern: 'src/assets/fake-test-file.pdf', included: false, watched: true, served: true}
|
||||
],
|
||||
|
||||
exclude: [
|
||||
@@ -58,6 +62,7 @@ module.exports = function (config) {
|
||||
plugins: [
|
||||
'karma-jasmine',
|
||||
'karma-coverage',
|
||||
'karma-jasmine-ajax',
|
||||
'karma-chrome-launcher',
|
||||
'karma-mocha-reporter',
|
||||
'karma-jasmine-html-reporter'
|
||||
@@ -75,7 +80,7 @@ module.exports = function (config) {
|
||||
coverageReporter: {
|
||||
dir: 'coverage/',
|
||||
subdir: 'report',
|
||||
reporters: [
|
||||
reporters: [
|
||||
{type: 'text'},
|
||||
{type: 'json', file: 'coverage-final.json'},
|
||||
{type: 'html'},
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "ng2-alfresco-viewer",
|
||||
"description": "Alfresco documents viewer",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"author": "Alfresco Software, Ltd.",
|
||||
"scripts": {
|
||||
"postinstall": "typings install",
|
||||
@@ -59,7 +59,7 @@
|
||||
"@angular/router-deprecated": "2.0.0-rc.2",
|
||||
"@angular/upgrade": "2.0.0-rc.3",
|
||||
|
||||
"ng2-alfresco-core": "0.2.0",
|
||||
"ng2-alfresco-core": "0.3.0",
|
||||
"ng2-translate": "2.2.2",
|
||||
"alfresco-js-api": "^0.3.0",
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"reflect-metadata": "0.1.3",
|
||||
"rxjs": "5.0.0-beta.6",
|
||||
"zone.js": "0.6.12",
|
||||
"pdfjs-dist": "1.5.258"
|
||||
"pdfjs-dist": "1.5.404"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"material-design-icons": "^2.2.3",
|
||||
|
@@ -1,64 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
export class PDFViewermock {
|
||||
|
||||
currentPageNumber: number = 1;
|
||||
|
||||
currentPage = {
|
||||
renderingState: 3 as number
|
||||
};
|
||||
|
||||
_pages: any =
|
||||
[{
|
||||
width: 793,
|
||||
scale: 1,
|
||||
update: this.update,
|
||||
div: {
|
||||
offsetTop: 400
|
||||
},
|
||||
viewport: {
|
||||
height: 400
|
||||
}
|
||||
}, {
|
||||
width: 793,
|
||||
scale: 1,
|
||||
update: this.update,
|
||||
div: {
|
||||
offsetTop: 800
|
||||
},
|
||||
viewport: {
|
||||
height: 400
|
||||
}
|
||||
}, {
|
||||
width: 793,
|
||||
scale: 1,
|
||||
update: this.update,
|
||||
div: {
|
||||
offsetTop: 1200
|
||||
},
|
||||
viewport: {
|
||||
height: 400
|
||||
}
|
||||
}];
|
||||
|
||||
_currentPageNumber: number = 0;
|
||||
|
||||
update() {
|
||||
}
|
||||
}
|
BIN
ng2-components/ng2-alfresco-viewer/src/assets/fake-test-file.pdf
Normal file
BIN
ng2-components/ng2-alfresco-viewer/src/assets/fake-test-file.pdf
Normal file
Binary file not shown.
@@ -0,0 +1,48 @@
|
||||
.viewer-video-row {
|
||||
display: -webkit-box;
|
||||
display: -moz-box;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
|
||||
-webkit-box-orient: horizontal;
|
||||
-moz-box-orient: horizontal;
|
||||
box-orient: horizontal;
|
||||
flex-direction: row;
|
||||
|
||||
-webkit-box-pack: center;
|
||||
-moz-box-pack: center;
|
||||
box-pack: center;
|
||||
justify-content: center;
|
||||
|
||||
-webkit-box-align: center;
|
||||
-moz-box-align: center;
|
||||
box-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.viewer-video-cell {
|
||||
-webkit-box-flex: 1;
|
||||
-moz-box-flex: 1;
|
||||
box-flex: 1;
|
||||
-webkit-flex: 1 1 auto;
|
||||
flex: 1 1 auto;
|
||||
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
video {
|
||||
max-height: 80vh;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
max-width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
<div class="viewer-video-content">
|
||||
<div class="viewer-video-row">
|
||||
<div class="viewer-video-cell">
|
||||
<video controls >
|
||||
<source [src]="urlFile" [type]="mimeType" />
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -0,0 +1,45 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Input, ViewEncapsulation } from '@angular/core';
|
||||
declare let __moduleName: string;
|
||||
|
||||
@Component({
|
||||
moduleId: __moduleName,
|
||||
selector: 'media-player',
|
||||
templateUrl: './mediaPlayer.component.html',
|
||||
styleUrls: ['./mediaPlayer.component.css'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class MediaPlayerComponent {
|
||||
|
||||
@Input()
|
||||
nameFile: string;
|
||||
|
||||
@Input()
|
||||
urlFile: string;
|
||||
|
||||
@Input()
|
||||
mimeType: string;
|
||||
|
||||
ngOnChanges(changes) {
|
||||
if (!this.urlFile) {
|
||||
throw new Error('Attribute urlFile is required');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,8 +1,3 @@
|
||||
.viewer-pdf-container {
|
||||
overflow: hidden;
|
||||
background: #3E3E3E;
|
||||
}
|
||||
|
||||
.loader-container {
|
||||
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
|
||||
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
|
@@ -4,7 +4,7 @@
|
||||
<div id="loader-container" class="loader-container">
|
||||
<div class="loader-item">
|
||||
<div id="loader-spin" class="mdl-progress mdl-js-progress mdl-progress__indeterminate"></div>
|
||||
<div id="loader-text" class="loader-text">Loading <span>{{nameFile}}</span> ...</div>
|
||||
<div id="loader-text" class="loader-text">Loading <span>{{nameFile}}</span> {{laodingPercent}}%</div>
|
||||
</div >
|
||||
</div>
|
||||
</div>
|
@@ -15,13 +15,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {describe, expect, it, inject, beforeEachProviders, beforeEach} from '@angular/core/testing';
|
||||
import {TestComponentBuilder} from '@angular/compiler/testing';
|
||||
import { describe, expect, it, inject, beforeEachProviders, beforeEach } from '@angular/core/testing';
|
||||
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||
import { RenderingQueueServices } from '../services/rendering-queue.services';
|
||||
|
||||
import {PdfViewerComponent} from './pdfViewer.component';
|
||||
import {PDFJSmock} from './assets/PDFJS.mock';
|
||||
import {PDFViewermock} from './assets/PDFViewer.mock';
|
||||
import {EventMock} from './assets/event.mock';
|
||||
import { PdfViewerComponent } from './pdfViewer.component';
|
||||
import { EventMock } from '../assets/event.mock';
|
||||
|
||||
import { AlfrescoAuthenticationService, AlfrescoSettingsService } from 'ng2-alfresco-core';
|
||||
|
||||
@@ -32,7 +31,8 @@ describe('PdfViewer', () => {
|
||||
beforeEachProviders(() => {
|
||||
return [
|
||||
AlfrescoSettingsService,
|
||||
AlfrescoAuthenticationService
|
||||
AlfrescoAuthenticationService,
|
||||
RenderingQueueServices
|
||||
];
|
||||
});
|
||||
|
||||
@@ -44,13 +44,8 @@ describe('PdfViewer', () => {
|
||||
element = fixture.nativeElement;
|
||||
component = fixture.componentInstance;
|
||||
|
||||
spyOn(component, 'getPDFJS').and.returnValue(new PDFJSmock());
|
||||
spyOn(component, 'initPDFViewer').and.callFake(() => {
|
||||
component.pdfViewer = new PDFViewermock();
|
||||
});
|
||||
|
||||
component.showToolbar = true;
|
||||
component.urlFile = 'fake-url-file';
|
||||
component.urlFile = 'base/src/assets/fake-test-file.pdf';
|
||||
pdfComponentFixture.detectChanges();
|
||||
});
|
||||
}));
|
||||
@@ -75,7 +70,6 @@ describe('PdfViewer', () => {
|
||||
expect(element.querySelector('#viewer-next-page-button')).not.toBeNull();
|
||||
});
|
||||
|
||||
|
||||
it('Input Page elements should be present', () => {
|
||||
pdfComponentFixture.detectChanges();
|
||||
|
||||
@@ -102,11 +96,13 @@ describe('PdfViewer', () => {
|
||||
component.inputPage(1);
|
||||
});
|
||||
|
||||
it('Total number of pages should be loaded', () => {
|
||||
it('Total number of pages should be loaded', (done) => {
|
||||
component.ngOnChanges().then(() => {
|
||||
expect(component.totalPages).toEqual('10');
|
||||
pdfComponentFixture.detectChanges();
|
||||
expect(component.totalPages).toEqual(4);
|
||||
done();
|
||||
});
|
||||
});
|
||||
}, 5000);
|
||||
|
||||
it('right arrow should move to the next page', (done) => {
|
||||
component.ngOnChanges().then(() => {
|
||||
@@ -117,7 +113,7 @@ describe('PdfViewer', () => {
|
||||
expect(component.displayPage).toBe(2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
}, 5000);
|
||||
|
||||
it('nextPage should move to the next page', (done) => {
|
||||
let nextPageButton = element.querySelector('#viewer-next-page-button');
|
||||
@@ -161,7 +157,6 @@ describe('PdfViewer', () => {
|
||||
});
|
||||
});
|
||||
|
||||
/* tslint:disable:max-line-length */
|
||||
it('previous page should not move to the previous page if is page 1', (done) => {
|
||||
component.ngOnChanges().then(() => {
|
||||
pdfComponentFixture.detectChanges();
|
||||
@@ -177,14 +172,13 @@ describe('PdfViewer', () => {
|
||||
component.ngOnChanges().then(() => {
|
||||
pdfComponentFixture.detectChanges();
|
||||
expect(component.displayPage).toBe(1);
|
||||
component.inputPage('4');
|
||||
component.inputPage('2');
|
||||
pdfComponentFixture.detectChanges();
|
||||
expect(component.displayPage).toBe(4);
|
||||
expect(component.displayPage).toBe(2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
/* tslint:disable:max-line-length */
|
||||
it('zoomIn should increment the scale value', (done) => {
|
||||
component.currentScale = 1;
|
||||
|
||||
@@ -194,7 +188,7 @@ describe('PdfViewer', () => {
|
||||
pdfComponentFixture.detectChanges();
|
||||
zoomInButton.click();
|
||||
expect(component.currentScaleMode).toBe('auto');
|
||||
expect(component.currentScale).toBe(1.1);
|
||||
expect(component.currentScale).toBe(0.9);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -205,20 +199,22 @@ describe('PdfViewer', () => {
|
||||
let zoomOutButton = element.querySelector('#viewer-zoom-out-button');
|
||||
|
||||
component.ngOnChanges().then(() => {
|
||||
component.inputPage('1');
|
||||
pdfComponentFixture.detectChanges();
|
||||
zoomOutButton.click();
|
||||
expect(component.currentScaleMode).toBe('auto');
|
||||
expect(component.currentScale).toBe(0.9);
|
||||
expect(component.currentScale).toBe(0.7);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('fit in button should toggle page-fit and auto scale mode', (done) => {
|
||||
it('fit-in button should toggle page-fit and auto scale mode', (done) => {
|
||||
component.currentScale = 1;
|
||||
|
||||
let fitPage = element.querySelector('#viewer-scale-page-button');
|
||||
|
||||
component.ngOnChanges().then(() => {
|
||||
component.inputPage('1');
|
||||
pdfComponentFixture.detectChanges();
|
||||
expect(component.currentScaleMode).toBe('auto');
|
||||
fitPage.click();
|
||||
@@ -227,20 +223,19 @@ describe('PdfViewer', () => {
|
||||
expect(component.currentScaleMode).toBe('auto');
|
||||
done();
|
||||
});
|
||||
});
|
||||
}, 5000);
|
||||
});
|
||||
|
||||
describe('Resize interaction', () => {
|
||||
it('resize event should trigger setScaleUpdatePages', () => {
|
||||
spyOn(component, 'setScaleUpdatePages');
|
||||
|
||||
component.documentContainer = element.querySelector('#viewer-pdf-container');
|
||||
component.pdfViewer = new PDFViewermock();
|
||||
component.urlFile = 'fake-url-file';
|
||||
|
||||
EventMock.resizeMobileView();
|
||||
|
||||
expect(component.setScaleUpdatePages).toHaveBeenCalled();
|
||||
it('resize event should trigger setScaleUpdatePages', (done) => {
|
||||
component.ngOnChanges().then(() => {
|
||||
pdfComponentFixture.detectChanges();
|
||||
spyOn(component, 'onResize');
|
||||
component.documentContainer = element.querySelector('#viewer-pdf-container');
|
||||
EventMock.resizeMobileView();
|
||||
expect(component.onResize).toHaveBeenCalled();
|
||||
done();
|
||||
}, 5000);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -249,10 +244,13 @@ describe('PdfViewer', () => {
|
||||
component.ngOnChanges().then(() => {
|
||||
pdfComponentFixture.detectChanges();
|
||||
expect(component.displayPage).toBe(1);
|
||||
component.inputPage('4');
|
||||
component.inputPage('2');
|
||||
pdfComponentFixture.detectChanges();
|
||||
expect(component.displayPage).toBe(2);
|
||||
let documentContainer = element.querySelector('#viewer-pdf-container');
|
||||
documentContainer.scrollTop = 100000;
|
||||
component.watchScroll(documentContainer);
|
||||
pdfComponentFixture.detectChanges();
|
||||
expect(component.displayPage).toBe(4);
|
||||
component.watchScroll({scrollTop: 10000});
|
||||
expect(component.displayPage).toBe(4);
|
||||
done();
|
||||
});
|
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
import { Component, Input, HostListener } from '@angular/core';
|
||||
import { RenderingQueueServices } from '../services/rendering-queue.services';
|
||||
|
||||
declare let PDFJS: any;
|
||||
declare let __moduleName: string;
|
||||
@@ -24,7 +25,8 @@ declare let __moduleName: string;
|
||||
moduleId: __moduleName,
|
||||
selector: 'pdf-viewer',
|
||||
templateUrl: './pdfViewer.component.html',
|
||||
styleUrls: ['./pdfViewer.component.css', './pdfViewerHost.component.css']
|
||||
styleUrls: ['./pdfViewer.component.css', './pdfViewerHost.component.css'],
|
||||
providers: [RenderingQueueServices]
|
||||
})
|
||||
export class PdfViewerComponent {
|
||||
|
||||
@@ -37,10 +39,12 @@ export class PdfViewerComponent {
|
||||
@Input()
|
||||
showToolbar: boolean = true;
|
||||
|
||||
|
||||
currentPdfDocument: any;
|
||||
page: number;
|
||||
displayPage: number;
|
||||
totalPages: number;
|
||||
laodingPercent: number;
|
||||
|
||||
pdfViewer: any;
|
||||
|
||||
@@ -52,6 +56,9 @@ export class PdfViewerComponent {
|
||||
MIN_SCALE: number = 0.25;
|
||||
MAX_SCALE: number = 10.0;
|
||||
|
||||
constructor(private renderingQueueServices: RenderingQueueServices) {
|
||||
}
|
||||
|
||||
ngOnChanges(changes) {
|
||||
if (!this.urlFile) {
|
||||
throw new Error('Attribute urlFile is required');
|
||||
@@ -59,7 +66,14 @@ export class PdfViewerComponent {
|
||||
|
||||
if (this.urlFile) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.getPDFJS().getDocument(this.urlFile, null, null).then((pdfDocument) => {
|
||||
let loadingTask = this.getPDFJS().getDocument(this.urlFile);
|
||||
|
||||
loadingTask.onProgress = (progressData) => {
|
||||
let level = progressData.loaded / progressData.total;
|
||||
this.laodingPercent = Math.round(level * 100);
|
||||
};
|
||||
|
||||
loadingTask.then((pdfDocument) => {
|
||||
this.currentPdfDocument = pdfDocument;
|
||||
this.totalPages = pdfDocument.numPages;
|
||||
this.page = 1;
|
||||
@@ -68,6 +82,7 @@ export class PdfViewerComponent {
|
||||
|
||||
this.currentPdfDocument.getPage(1).then(() => {
|
||||
this.scalePage('auto');
|
||||
resolve();
|
||||
}, (error) => {
|
||||
reject(error);
|
||||
});
|
||||
@@ -75,7 +90,6 @@ export class PdfViewerComponent {
|
||||
}, (error) => {
|
||||
reject(error);
|
||||
});
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -90,7 +104,7 @@ export class PdfViewerComponent {
|
||||
}
|
||||
|
||||
initPDFViewer(pdfDocument: any) {
|
||||
PDFJS.verbosity = 5;
|
||||
PDFJS.verbosity = 1;
|
||||
PDFJS.disableWorker = true;
|
||||
|
||||
let documentContainer = document.getElementById('viewer-pdf-container');
|
||||
@@ -102,9 +116,12 @@ export class PdfViewerComponent {
|
||||
|
||||
this.pdfViewer = new PDFJS.PDFViewer({
|
||||
container: documentContainer,
|
||||
viewer: viewer
|
||||
viewer: viewer,
|
||||
renderingQueue: this.renderingQueueServices
|
||||
});
|
||||
|
||||
this.renderingQueueServices.setViewer(this.pdfViewer);
|
||||
|
||||
this.pdfViewer.setDocument(pdfDocument);
|
||||
}
|
||||
|
||||
@@ -313,6 +330,7 @@ export class PdfViewerComponent {
|
||||
*/
|
||||
watchScroll(target) {
|
||||
let outputPage = this.getVisibleElement(target);
|
||||
|
||||
if (outputPage) {
|
||||
this.page = outputPage.id;
|
||||
this.displayPage = this.page;
|
@@ -164,7 +164,52 @@
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: url('images/loading-icon.gif') center no-repeat;
|
||||
}
|
||||
|
||||
:host .loadingIcon {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
left: 50% !important;
|
||||
top: 50% !important;
|
||||
|
||||
margin-top: -50px;
|
||||
margin-left: -50px;
|
||||
|
||||
font-size: 5px;
|
||||
text-indent: -9999em;
|
||||
border-top: 1.1em solid rgba(3,0,2, 0.2);
|
||||
border-right: 1.1em solid rgba(3,0,2, 0.2);
|
||||
border-bottom: 1.1em solid rgba(3,0,2, 0.2);
|
||||
border-left: 1.1em solid #030002;
|
||||
-webkit-transform: translateZ(0);
|
||||
-ms-transform: translateZ(0);
|
||||
transform: translateZ(0);
|
||||
-webkit-animation: load8 1.1s infinite linear;
|
||||
animation: load8 1.1s infinite linear;
|
||||
}
|
||||
:host .loadingIcon,
|
||||
:host .loadingIcon:after {
|
||||
border-radius: 50%;
|
||||
}
|
||||
@-webkit-keyframes load8 {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes load8 {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
:host * {
|
||||
@@ -200,3 +245,21 @@ select {
|
||||
:host [hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
#viewer-pdf-container {
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
position: absolute;
|
||||
top: 32px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
outline: none;
|
||||
}
|
||||
html[dir='ltr'] #viewer-pdf-container {
|
||||
box-shadow: inset 1px 0 0 hsla(0,0%,100%,.05);
|
||||
}
|
||||
html[dir='rtl'] #viewer-pdf-container {
|
||||
box-shadow: inset -1px 0 0 hsla(0,0%,100%,.05);
|
||||
}
|
@@ -55,7 +55,3 @@ img-viewer {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.viewer-content-container {
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
}
|
@@ -43,21 +43,22 @@
|
||||
<!--</button>-->
|
||||
<!--</div>-->
|
||||
|
||||
<div *ngIf="isLoaded()" class="center-element mdl-cell mdl-cell--12-col" >
|
||||
<div id="viewer-content-container" *ngIf="isLoaded()" class="center-element mdl-cell mdl-cell--12-col" >
|
||||
|
||||
<div id="viewer-content-container" class="viewer-content-container mdl-cell" >
|
||||
<!-- Start View Switch-->
|
||||
<div *ngIf="isPdf()">
|
||||
<pdf-viewer [showToolbar]="showToolbar" [urlFile]="urlFile" [nameFile]="displayName" ></pdf-viewer>
|
||||
<pdf-viewer [showToolbar]="showToolbar" [urlFile]="urlFileContent" [nameFile]="displayName" ></pdf-viewer>
|
||||
</div>
|
||||
<div class="center-element" *ngIf="isImage()" >
|
||||
<img-viewer [urlFile]="urlFile" [nameFile]="displayName"></img-viewer>
|
||||
<img-viewer [urlFile]="urlFileContent" [nameFile]="displayName"></img-viewer>
|
||||
</div>
|
||||
<div class="center-element" *ngIf="isMedia()" >
|
||||
<media-player [urlFile]="urlFileContent" [mimeType]="mimeType" [nameFile]="displayName"></media-player>
|
||||
</div>
|
||||
<div *ngIf="!supportedExtension()">
|
||||
<not-supported-format [urlFile]="urlFile" [nameFile]="displayName" ></not-supported-format>
|
||||
<not-supported-format [urlFile]="urlFileContent" [nameFile]="displayName" ></not-supported-format>
|
||||
</div>
|
||||
<!-- End View Switch -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@@ -15,11 +15,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {describe, expect, it, inject, beforeEachProviders, beforeEach} from '@angular/core/testing';
|
||||
import {TestComponentBuilder} from '@angular/compiler/testing';
|
||||
import {ViewerComponent} from './viewer.component';
|
||||
import {EventMock} from './assets/event.mock';
|
||||
import { AlfrescoApiService, AlfrescoAuthenticationService, AlfrescoSettingsService } from 'ng2-alfresco-core';
|
||||
import { describe, expect, it, inject, beforeEachProviders, beforeEach, afterEach } from '@angular/core/testing';
|
||||
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||
import { ViewerComponent } from './viewer.component';
|
||||
import { EventMock } from '../assets/event.mock';
|
||||
import { AlfrescoAuthenticationService, AlfrescoSettingsService, AlfrescoApiService } from 'ng2-alfresco-core';
|
||||
import { RenderingQueueServices } from '../services/rendering-queue.services';
|
||||
|
||||
declare let jasmine: any;
|
||||
|
||||
describe('ViewerComponent', () => {
|
||||
|
||||
@@ -29,7 +32,8 @@ describe('ViewerComponent', () => {
|
||||
return [
|
||||
AlfrescoApiService,
|
||||
AlfrescoSettingsService,
|
||||
AlfrescoAuthenticationService
|
||||
AlfrescoAuthenticationService,
|
||||
RenderingQueueServices
|
||||
];
|
||||
});
|
||||
|
||||
@@ -41,13 +45,20 @@ describe('ViewerComponent', () => {
|
||||
element = viewerComponentFixture.nativeElement;
|
||||
component = viewerComponentFixture.componentInstance;
|
||||
|
||||
component.urlFile = 'fake-url-file';
|
||||
jasmine.Ajax.install();
|
||||
|
||||
component.urlFile = 'base/src/assets/fake-test-file.pdf';
|
||||
|
||||
component.overlayMode = true;
|
||||
|
||||
viewerComponentFixture.detectChanges();
|
||||
});
|
||||
}));
|
||||
|
||||
afterEach(() => {
|
||||
jasmine.Ajax.uninstall();
|
||||
});
|
||||
|
||||
describe('View', () => {
|
||||
it('shadow overlay should be present if is overlay mode', () => {
|
||||
expect(element.querySelector('#viewer-shadow-transparent')).not.toBeNull();
|
||||
@@ -66,17 +77,15 @@ describe('ViewerComponent', () => {
|
||||
});
|
||||
|
||||
it('Name File should be present if is overlay mode ', () => {
|
||||
component.urlFile = 'http://localhost:9876/fake-url-file.pdf';
|
||||
component.overlayMode = true;
|
||||
|
||||
component.ngOnChanges().then(() => {
|
||||
viewerComponentFixture.detectChanges();
|
||||
expect(element.querySelector('#viewer-name-file').innerHTML).toEqual('fake-url-file.pdf');
|
||||
expect(element.querySelector('#viewer-name-file').innerHTML).toEqual('fake-test-file.pdf');
|
||||
});
|
||||
});
|
||||
|
||||
it('Close button should be present if overlay mode', () => {
|
||||
component.urlFile = 'fake-url-file';
|
||||
component.overlayMode = true;
|
||||
|
||||
viewerComponentFixture.detectChanges();
|
||||
@@ -85,7 +94,6 @@ describe('ViewerComponent', () => {
|
||||
});
|
||||
|
||||
it('Close button should be not present if is not overlay mode', () => {
|
||||
component.urlFile = 'fake-url-file';
|
||||
component.overlayMode = false;
|
||||
|
||||
viewerComponentFixture.detectChanges();
|
||||
@@ -94,7 +102,6 @@ describe('ViewerComponent', () => {
|
||||
});
|
||||
|
||||
it('Click on close button should hide the viewer', () => {
|
||||
component.urlFile = 'fake-url-file';
|
||||
component.overlayMode = true;
|
||||
|
||||
viewerComponentFixture.detectChanges();
|
||||
@@ -107,8 +114,6 @@ describe('ViewerComponent', () => {
|
||||
it('Esc button should not hide the viewerls if is not overlay mode', () => {
|
||||
component.overlayMode = false;
|
||||
|
||||
component.urlFile = 'fake-url-file';
|
||||
|
||||
viewerComponentFixture.detectChanges();
|
||||
EventMock.keyDown(27);
|
||||
viewerComponentFixture.detectChanges();
|
||||
@@ -116,7 +121,6 @@ describe('ViewerComponent', () => {
|
||||
});
|
||||
|
||||
it('Esc button should hide the viewer', () => {
|
||||
component.urlFile = 'fake-url-file';
|
||||
component.overlayMode = true;
|
||||
|
||||
viewerComponentFixture.detectChanges();
|
||||
@@ -128,8 +132,9 @@ describe('ViewerComponent', () => {
|
||||
});
|
||||
|
||||
describe('Attribute', () => {
|
||||
it('Url File should be mandatory', () => {
|
||||
it('Url or fileNodeId File should be mandatory', () => {
|
||||
component.showViewer = true;
|
||||
component.fileNodeId = undefined;
|
||||
component.urlFile = undefined;
|
||||
|
||||
expect(() => {
|
||||
@@ -137,12 +142,53 @@ describe('ViewerComponent', () => {
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('If FileNodeId is present should not be thrown any error ', () => {
|
||||
component.showViewer = true;
|
||||
component.fileNodeId = 'file-node-id';
|
||||
component.urlFile = undefined;
|
||||
|
||||
expect(() => {
|
||||
component.ngOnChanges();
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('If urlFile is present should not be thrown any error ', () => {
|
||||
component.showViewer = true;
|
||||
component.fileNodeId = undefined;
|
||||
|
||||
expect(() => {
|
||||
component.ngOnChanges();
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('If FileNodeId is present the node api should be called', (done) => {
|
||||
component.showViewer = true;
|
||||
component.fileNodeId = 'file-node-id';
|
||||
component.urlFile = undefined;
|
||||
|
||||
jasmine.Ajax.stubRequest(
|
||||
'http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/nodes/file-node-id'
|
||||
).andReturn({
|
||||
status: 200,
|
||||
responseText: '{"entry":{"isFile":true,"createdByUser":{"id":"admin","displayName":"Administrator"},' +
|
||||
'"modifiedAt":"2016-08-05T23:08:22.730+0000","nodeType":"cm:content","content":' +
|
||||
'{"mimeType":"application/pdf","mimeTypeName":"Adobe PDF Document","sizeInBytes":' +
|
||||
'381778,"encoding":"UTF-8"},"parentId":"8f2105b4-daaf-4874-9e8a-2152569d109b","createdAt":"2016-08-05T23:08:22.730+0000","isFolder":false,' +
|
||||
'"modifiedByUser":{"id":"admin","displayName":"Administrator"},"name":"content.pdf","id":' +
|
||||
'"b8bd4c81-6f2e-4ec2-9c4d-30c97cf42bc8"}}'
|
||||
});
|
||||
|
||||
component.ngOnChanges().then(() => {
|
||||
expect(jasmine.Ajax.requests.mostRecent().url.endsWith('nodes/file-node-id')).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('showViewer default value should be true', () => {
|
||||
expect(component.showViewer).toBe(true);
|
||||
});
|
||||
|
||||
it('if showViewer value is false the viewer should be hide', () => {
|
||||
component.urlFile = 'fake-url-file';
|
||||
component.showViewer = false;
|
||||
|
||||
viewerComponentFixture.detectChanges();
|
||||
@@ -152,7 +198,7 @@ describe('ViewerComponent', () => {
|
||||
|
||||
describe('Extension Type Test', () => {
|
||||
it('if extension file is a pdf the pdf viewer should be loaded', (done) => {
|
||||
component.urlFile = 'fake-url-file.pdf';
|
||||
component.urlFile = 'base/src/assets/fake-test-file.pdf';
|
||||
|
||||
component.ngOnChanges().then(() => {
|
||||
viewerComponentFixture.detectChanges();
|
||||
@@ -171,6 +217,16 @@ describe('ViewerComponent', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('if extension file is a video the the media player should be loaded', (done) => {
|
||||
component.urlFile = 'fake-url-file.mp4';
|
||||
|
||||
component.ngOnChanges().then(() => {
|
||||
viewerComponentFixture.detectChanges();
|
||||
expect(element.querySelector('media-player')).not.toBeNull();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('if extension file is a not supported the not supported div should be loaded', (done) => {
|
||||
component.urlFile = 'fake-url-file.unsupported';
|
||||
|
||||
@@ -227,5 +283,27 @@ describe('ViewerComponent', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should display the media player if the file identified by mimetype is a media when the filename has wrong extension', (done) => {
|
||||
component.urlFile = 'content.bin';
|
||||
component.mimeType = 'video/mp4';
|
||||
|
||||
component.ngOnChanges().then(() => {
|
||||
viewerComponentFixture.detectChanges();
|
||||
expect(element.querySelector('media-player')).not.toBeNull();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should display the media player if the file identified by mimetype is a media when the filename has no extension', (done) => {
|
||||
component.urlFile = 'content';
|
||||
component.mimeType = 'video/mp4';
|
||||
|
||||
component.ngOnChanges().then(() => {
|
||||
viewerComponentFixture.detectChanges();
|
||||
expect(element.querySelector('media-player')).not.toBeNull();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@@ -18,24 +18,26 @@
|
||||
import { Component, ElementRef, Input, Output, HostListener, EventEmitter, Inject } from '@angular/core';
|
||||
import { PdfViewerComponent } from './pdfViewer.component';
|
||||
import { ImgViewerComponent } from './imgViewer.component';
|
||||
import { MediaPlayerComponent } from './mediaPlayer.component';
|
||||
import { NotSupportedFormat } from './notSupportedFormat.component';
|
||||
import { DOCUMENT } from '@angular/platform-browser';
|
||||
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
|
||||
import { AlfrescoApiService } from 'ng2-alfresco-core';
|
||||
import { AlfrescoAuthenticationService } from 'ng2-alfresco-core';
|
||||
|
||||
declare let __moduleName: string;
|
||||
|
||||
@Component({
|
||||
moduleId: __moduleName,
|
||||
selector: 'alfresco-viewer',
|
||||
directives: [PdfViewerComponent, ImgViewerComponent, NotSupportedFormat],
|
||||
directives: [PdfViewerComponent, ImgViewerComponent, NotSupportedFormat, MediaPlayerComponent],
|
||||
templateUrl: './viewer.component.html',
|
||||
styleUrls: ['./viewer.component.css']
|
||||
})
|
||||
export class ViewerComponent {
|
||||
|
||||
@Input()
|
||||
urlFile: string;
|
||||
urlFile: string = '';
|
||||
|
||||
@Input()
|
||||
fileNodeId: string = null;
|
||||
@@ -52,6 +54,8 @@ export class ViewerComponent {
|
||||
@Output()
|
||||
showViewerChange: EventEmitter<boolean> = new EventEmitter<boolean>();
|
||||
|
||||
urlFileContent: string;
|
||||
|
||||
otherMenu: any;
|
||||
|
||||
displayName: string;
|
||||
@@ -74,25 +78,26 @@ export class ViewerComponent {
|
||||
if (!this.urlFile && !this.fileNodeId) {
|
||||
throw new Error('Attribute urlFile or fileNodeId is required');
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let alfrescoApi = this.apiService.getInstance();
|
||||
if (this.urlFile) {
|
||||
let filenameFromUrl = this.getFilenameFromUrl(this.urlFile);
|
||||
this.displayName = filenameFromUrl ? filenameFromUrl : '';
|
||||
this.extension = this.getFileExtension(filenameFromUrl);
|
||||
this.urlFileContent = this.urlFile;
|
||||
resolve();
|
||||
} else if (this.fileNodeId) {
|
||||
alfrescoApi.nodes.getNodeInfo(this.fileNodeId).then((data: MinimalNodeEntryEntity) => {
|
||||
this.mimeType = data.content.mimeType;
|
||||
this.displayName = data.name;
|
||||
this.urlFile = alfrescoApi.content.getContentUrl(data.id);
|
||||
this.urlFileContent = alfrescoApi.content.getContentUrl(data.id);
|
||||
this.loaded = true;
|
||||
resolve();
|
||||
}, function (error) {
|
||||
reject(error);
|
||||
console.log('This node does not exist');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -105,10 +110,24 @@ export class ViewerComponent {
|
||||
if (this.otherMenu) {
|
||||
this.otherMenu.hidden = false;
|
||||
}
|
||||
this.cleanup();
|
||||
this.showViewer = false;
|
||||
this.showViewerChange.emit(this.showViewer);
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
this.urlFileContent = '';
|
||||
this.displayName = '';
|
||||
this.fileNodeId = null;
|
||||
this.loaded = false;
|
||||
this.extension = null;
|
||||
this.mimeType = null;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* get File name from url
|
||||
*
|
||||
@@ -134,7 +153,7 @@ export class ViewerComponent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the content is an image thorugh the extension or mime type
|
||||
* Check if the content is an image through the extension or mime type
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
@@ -142,6 +161,16 @@ export class ViewerComponent {
|
||||
return this.isImageExtension() || this.isImageMimeType();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the content is a media through the extension or mime type
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
private isMedia() {
|
||||
return this.isMediaExtension() || this.isMediaMimeType();
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the current file is a supported image extension
|
||||
*
|
||||
@@ -152,6 +181,24 @@ export class ViewerComponent {
|
||||
this.extension === 'jpeg' || this.extension === 'gif' || this.extension === 'bmp';
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the current file has an image-based mimetype
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
private isMediaMimeType() {
|
||||
return this.mimeType && this.mimeType.indexOf('video/') === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the current file is a supported media extension
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
private isMediaExtension() {
|
||||
return this.extension === 'mp4' || this.extension === 'WebM' || this.extension === 'Ogg';
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the current file has an image-based mimetype
|
||||
*
|
||||
@@ -176,7 +223,7 @@ export class ViewerComponent {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
supportedExtension() {
|
||||
return this.isImage() || this.isPdf();
|
||||
return this.isImage() || this.isPdf() || this.isMedia();
|
||||
}
|
||||
|
||||
/**
|
@@ -0,0 +1,39 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { it, describe, inject, beforeEach, beforeEachProviders, expect } from '@angular/core/testing';
|
||||
import { RenderingQueueServices } from './rendering-queue.services';
|
||||
|
||||
|
||||
describe('RenderingQueueServices', () => {
|
||||
|
||||
let service;
|
||||
|
||||
beforeEachProviders(() => {
|
||||
return [
|
||||
RenderingQueueServices
|
||||
];
|
||||
});
|
||||
|
||||
beforeEach(inject([RenderingQueueServices], (renderingQueueServices: RenderingQueueServices) => {
|
||||
service = renderingQueueServices;
|
||||
}));
|
||||
|
||||
it('Simple import example', () => {
|
||||
expect(service.CLEANUP_TIMEOUT).toEqual(30000);
|
||||
});
|
||||
});
|
@@ -0,0 +1,171 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
/**
|
||||
*
|
||||
* RenderingQueueServices rendering of the views for pages and thumbnails.
|
||||
*
|
||||
* @returns {RenderingQueueServices} .
|
||||
*/
|
||||
@Injectable()
|
||||
export class RenderingQueueServices {
|
||||
|
||||
renderingStates = {
|
||||
INITIAL: 0,
|
||||
RUNNING: 1,
|
||||
PAUSED: 2,
|
||||
FINISHED: 3
|
||||
};
|
||||
|
||||
CLEANUP_TIMEOUT: number = 30000;
|
||||
|
||||
pdfViewer: any = null;
|
||||
pdfThumbnailViewer: any = null;
|
||||
onIdle: any = null;
|
||||
|
||||
highestPriorityPage: any = null;
|
||||
idleTimeout: any = null;
|
||||
printing: any = false;
|
||||
isThumbnailViewEnabled: any = false;
|
||||
|
||||
/**
|
||||
* @param {PDFViewer} pdfViewer
|
||||
*/
|
||||
setViewer(pdfViewer) {
|
||||
this.pdfViewer = pdfViewer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PDFThumbnailViewer} pdfThumbnailViewer
|
||||
*/
|
||||
setThumbnailViewer(pdfThumbnailViewer) {
|
||||
this.pdfThumbnailViewer = pdfThumbnailViewer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {IRenderableView} view
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isHighestPriority(view: any) {
|
||||
return this.highestPriorityPage === view.renderingId;
|
||||
}
|
||||
|
||||
renderHighestPriority(currentlyVisiblePages) {
|
||||
if (this.idleTimeout) {
|
||||
clearTimeout(this.idleTimeout);
|
||||
this.idleTimeout = null;
|
||||
}
|
||||
|
||||
// Pages have a higher priority than thumbnails, so check them first.
|
||||
if (this.pdfViewer.forceRendering(currentlyVisiblePages)) {
|
||||
return;
|
||||
}
|
||||
// No pages needed rendering so check thumbnails.
|
||||
if (this.pdfThumbnailViewer && this.isThumbnailViewEnabled) {
|
||||
if (this.pdfThumbnailViewer.forceRendering()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.printing) {
|
||||
// If printing is currently ongoing do not reschedule cleanup.
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.onIdle) {
|
||||
this.idleTimeout = setTimeout(this.onIdle.bind(this), this.CLEANUP_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
getHighestPriority(visible, views, scrolledDown) {
|
||||
// The state has changed figure out which page has the highest priority to
|
||||
// render next (if any).
|
||||
// Priority:
|
||||
// 1 visible pages
|
||||
// 2 if last scrolled down page after the visible pages
|
||||
// 2 if last scrolled up page before the visible pages
|
||||
let visibleViews = visible.views;
|
||||
|
||||
let numVisible = visibleViews.length;
|
||||
if (numVisible === 0) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < numVisible; ++i) {
|
||||
let view = visibleViews[i].view;
|
||||
if (!this.isViewFinished(view)) {
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
// All the visible views have rendered, try to render next/previous pages.
|
||||
if (scrolledDown) {
|
||||
let nextPageIndex = visible.last.id;
|
||||
// ID's start at 1 so no need to add 1.
|
||||
if (views[nextPageIndex] && !this.isViewFinished(views[nextPageIndex])) {
|
||||
return views[nextPageIndex];
|
||||
}
|
||||
} else {
|
||||
let previousPageIndex = visible.first.id - 2;
|
||||
if (views[previousPageIndex] && !this.isViewFinished(views[previousPageIndex])) {
|
||||
return views[previousPageIndex];
|
||||
}
|
||||
}
|
||||
// Everything that needs to be rendered has been.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {IRenderableView} view
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isViewFinished(view) {
|
||||
return view.renderingState === this.renderingStates.FINISHED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a page or thumbnail view. This calls the appropriate function
|
||||
* based on the views state. If the view is already rendered it will return
|
||||
* false.
|
||||
* @param {IRenderableView} view
|
||||
*/
|
||||
renderView(view: any) {
|
||||
let state = view.renderingState;
|
||||
switch (state) {
|
||||
case this.renderingStates.FINISHED:
|
||||
return false;
|
||||
case this.renderingStates.PAUSED:
|
||||
this.highestPriorityPage = view.renderingId;
|
||||
view.resume();
|
||||
break;
|
||||
case this.renderingStates.RUNNING:
|
||||
this.highestPriorityPage = view.renderingId;
|
||||
break;
|
||||
case this.renderingStates.INITIAL:
|
||||
this.highestPriorityPage = view.renderingId;
|
||||
let continueRendering = function () {
|
||||
this.renderHighestPriority();
|
||||
}.bind(this);
|
||||
view.draw().then(continueRendering, continueRendering);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user