Commit 7be07669 authored by Konstantin Schulz's avatar Konstantin Schulz
Browse files

added display page for static exercises so they can be accessed via deep links

parent d1625e52
......@@ -24,7 +24,6 @@ node_modules/
tmp/
temp/
hooks/
package-lock.json
platforms/
plugins/
plugins/android.json
......
......@@ -1250,6 +1250,7 @@
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
"dev": true,
"optional": true,
"requires": {
"delegates": "^1.0.0",
"readable-stream": "^2.0.6"
......@@ -2466,7 +2467,8 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
"dev": true
"dev": true,
"optional": true
},
"constants-browserify": {
"version": "1.0.0",
......@@ -3550,7 +3552,8 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
"dev": true
"dev": true,
"optional": true
},
"depd": {
"version": "1.1.2",
......@@ -5050,6 +5053,7 @@
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
"integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
"dev": true,
"optional": true,
"requires": {
"graceful-fs": "^4.1.2",
"inherits": "~2.0.0",
......@@ -5062,6 +5066,7 @@
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
"dev": true,
"optional": true,
"requires": {
"aproba": "^1.0.3",
"console-control-strings": "^1.0.0",
......@@ -5099,7 +5104,8 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
"integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
"dev": true
"dev": true,
"optional": true
},
"get-stream": {
"version": "3.0.0",
......@@ -5279,7 +5285,8 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
"dev": true
"dev": true,
"optional": true
},
"has-value": {
"version": "1.0.0",
......@@ -6005,7 +6012,8 @@
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
"integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
"dev": true
"dev": true,
"optional": true
},
"is-windows": {
"version": "1.0.2",
......@@ -6633,6 +6641,7 @@
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
"dev": true,
"optional": true,
"requires": {
"graceful-fs": "^4.1.2",
"parse-json": "^2.2.0",
......@@ -6645,7 +6654,8 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
"dev": true,
"optional": true
}
}
},
......@@ -6906,7 +6916,8 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
"integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
"dev": true
"dev": true,
"optional": true
},
"map-visit": {
"version": "1.0.0",
......@@ -7524,6 +7535,7 @@
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
"dev": true,
"optional": true,
"requires": {
"are-we-there-yet": "~1.1.2",
"console-control-strings": "~1.1.0",
......@@ -8543,6 +8555,7 @@
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
"integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
"dev": true,
"optional": true,
"requires": {
"load-json-file": "^1.0.0",
"normalize-package-data": "^2.3.2",
......@@ -8554,6 +8567,7 @@
"resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
"integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
"dev": true,
"optional": true,
"requires": {
"graceful-fs": "^4.1.2",
"pify": "^2.0.0",
......@@ -8564,7 +8578,8 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
"dev": true,
"optional": true
}
}
},
......@@ -8573,6 +8588,7 @@
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
"integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
"dev": true,
"optional": true,
"requires": {
"find-up": "^1.0.0",
"read-pkg": "^1.0.0"
......@@ -8583,6 +8599,7 @@
"resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
"integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
"dev": true,
"optional": true,
"requires": {
"path-exists": "^2.0.0",
"pinkie-promise": "^2.0.0"
......@@ -8593,6 +8610,7 @@
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
"integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
"dev": true,
"optional": true,
"requires": {
"pinkie-promise": "^2.0.0"
}
......@@ -9905,6 +9923,7 @@
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
"integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
"dev": true,
"optional": true,
"requires": {
"is-utf8": "^0.2.0"
}
......@@ -11245,6 +11264,7 @@
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
"dev": true,
"optional": true,
"requires": {
"string-width": "^1.0.2 || 2"
}
......
......@@ -18,7 +18,8 @@ const routes: Routes = [
{ path: 'sources', loadChildren: './sources/sources.module#SourcesPageModule' },
{ path: 'test', loadChildren: './test/test.module#TestPageModule' },
{ path: 'text-range', loadChildren: './text-range/text-range.module#TextRangePageModule' },
{ path: 'vocabulary-check', loadChildren: './vocabulary-check/vocabulary-check.module#VocabularyCheckPageModule' },
{ path: 'vocabulary-check', loadChildren: './vocabulary-check/vocabulary-check.module#VocabularyCheckPageModule' }, { path: 'exercise', loadChildren: './exercise/exercise.module#ExercisePageModule' },
];
......
/* tslint:disable:no-string-literal */
import {Injectable} from '@angular/core';
@Injectable({
......
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms';
import {Routes, RouterModule} from '@angular/router';
import {IonicModule} from '@ionic/angular';
import {ExercisePage} from './exercise.page';
import {TranslateModule} from '@ngx-translate/core';
const routes: Routes = [
{
path: '',
component: ExercisePage
}
];
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
RouterModule.forChild(routes),
TranslateModule.forChild()
],
declarations: [ExercisePage]
})
export class ExercisePageModule {
}
<ion-header>
<ion-toolbar>
<div class="toolbar-left">
<ion-title>{{ 'EXERCISE' | translate }}</ion-title>
</div>
<div class="toolbar-right">
<ion-spinner *ngIf="HelperService.isLoading"></ion-spinner>
<button (click)="HelperService.goToHomePage(navCtrl)">
<ion-icon name="home"></ion-icon>
</button>
</div>
</ion-toolbar>
</ion-header>
<ion-content>
<div class="h5p-container"></div>
</ion-content>
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ExercisePage } from './exercise.page';
describe('ExercisePage', () => {
let component: ExercisePage;
let fixture: ComponentFixture<ExercisePage>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ExercisePage ],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ExercisePage);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
/* tslint:disable:no-string-literal */
import {Component, OnInit} from '@angular/core';
import {HelperService} from '../helper.service';
import {NavController} from '@ionic/angular';
import {ActivatedRoute} from '@angular/router';
import {TranslateService} from '@ngx-translate/core';
declare var H5P: any;
// dirty hack to prevent H5P access errors after resize events
window.onresize = () => {
/* tslint:disable:prefer-const */
/* tslint:disable:no-shadowed-variable */
let H5P: any;
/* tslint:enable:prefer-const */
/* tslint:enable:no-shadowed-variable */
};
@Component({
selector: 'app-exercise',
templateUrl: './exercise.page.html',
styleUrls: ['./exercise.page.scss'],
})
export class ExercisePage implements OnInit {
HelperService = HelperService;
constructor(public navCtrl: NavController,
public activatedRoute: ActivatedRoute,
public translateService: TranslateService) {
this.activatedRoute.queryParams.subscribe((params: object) => {
const exerciseType: string = params['type'];
const file: string = params['file'];
const lang: string = this.translateService.currentLang;
window.localStorage.setItem(HelperService.config['localStorageKeyH5P'],
HelperService.baseUrl + '/assets/h5p/' + exerciseType + '/content/' + file + '_' + lang + '.json');
// dirty hack to get H5P going without explicit button click on the new page
setTimeout(() => {
H5P.jQuery('.h5p-container').empty().h5p({
frameJs: 'assets/dist/js/h5p-standalone-frame.min.js',
frameCss: 'assets/dist/styles/h5p.css',
h5pContent: 'assets/h5p/' + exerciseType
});
}, 50);
});
}
ngOnInit() {
}
}
......@@ -170,13 +170,10 @@ export class HelperService {
initConfig() {
this.http.get('assets/config.json').subscribe((config: object) => {
HelperService.config = config;
// tslint:disable-next-line:no-string-literal
if (!HelperService.config['backendBaseUrl']) {
const part1: string = location.protocol.concat('//').concat(window.location.host);
// tslint:disable-next-line:no-string-literal
HelperService.config['backendBaseUrl'] = part1.concat(HelperService.config['backendBaseApiPath']).concat('/');
}
// tslint:disable-next-line:no-string-literal
const mrs: string = window.localStorage.getItem(HelperService.config['localStorageKeyMostRecentSetup']);
HelperService.mostRecentSetup = JSON.parse(mrs);
});
......
......@@ -15,7 +15,6 @@ import Context from 'src/app/models/xAPI/Context';
import {TestResultMC} from 'src/app/models/testResultMC';
declare var H5P: any;
declare var $: any;
// dirty hack to prevent H5P access errors after resize events
window.onresize = () => {
/* tslint:disable:prefer-const */
......
......@@ -55,6 +55,7 @@
"ERROR_CITATIONS_UNAVAILABLE": "Zitierschema nicht verfügbar :(",
"ERROR_CORPORA_UNAVAILABLE": "Korpora nicht verfügbar :(",
"ERROR_GENERAL_ALERT": "Huch, da ist etwas schief gelaufen... :(",
"EXERCISE": "Übung",
"EXERCISE_DOWNLOAD_NEXT_STEPS": "Nächste Schritte (XML)",
"EXERCISE_FEEDBACK": "Feedback",
"EXERCISE_FEEDBACK_CORRECT": "korrekt",
......
......@@ -55,6 +55,7 @@
"ERROR_CITATIONS_UNAVAILABLE": "Citation scheme unavailable :(",
"ERROR_CORPORA_UNAVAILABLE": "Corpora unavailable :(",
"ERROR_GENERAL_ALERT": "Oops, something went wrong... :(",
"EXERCISE": "Exercise",
"EXERCISE_DOWNLOAD_NEXT_STEPS": "Next steps (XML)",
"EXERCISE_FEEDBACK": "Feedback",
"EXERCISE_FEEDBACK_CORRECT": "correct",
......
......@@ -18,6 +18,84 @@
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
<!-- polyfill for Array.from in IE11 -->
<!-- <script type="text/javascript">-->
<!-- // Production steps of ECMA-262, Edition 6, 22.1.2.1-->
<!-- if (!Array.from) {-->
<!-- Array.from = (function () {-->
<!-- var toStr = Object.prototype.toString;-->
<!-- var isCallable = function (fn) {-->
<!-- return typeof fn === 'function' || toStr.call(fn) === '[object Function]';-->
<!-- };-->
<!-- var toInteger = function (value) {-->
<!-- var number = Number(value);-->
<!-- if (isNaN(number)) {-->
<!-- return 0;-->
<!-- }-->
<!-- if (number === 0 || !isFinite(number)) {-->
<!-- return number;-->
<!-- }-->
<!-- return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));-->
<!-- };-->
<!-- var maxSafeInteger = Math.pow(2, 53) - 1;-->
<!-- var toLength = function (value) {-->
<!-- var len = toInteger(value);-->
<!-- return Math.min(Math.max(len, 0), maxSafeInteger);-->
<!-- };-->
<!-- // The length property of the from method is 1.-->
<!-- return function from(arrayLike/*, mapFn, thisArg */) {-->
<!-- // 1. Let C be the this value.-->
<!-- var C = this;-->
<!-- // 2. Let items be ToObject(arrayLike).-->
<!-- var items = Object(arrayLike);-->
<!-- // 3. ReturnIfAbrupt(items).-->
<!-- if (arrayLike == null) {-->
<!-- throw new TypeError('Array.from requires an array-like object - not null or undefined');-->
<!-- }-->
<!-- // 4. If mapfn is undefined, then let mapping be false.-->
<!-- var mapFn = arguments.length > 1 ? arguments[1] : void undefined;-->
<!-- var T;-->
<!-- if (typeof mapFn !== 'undefined') {-->
<!-- // 5. else-->
<!-- // 5. a If IsCallable(mapfn) is false, throw a TypeError exception.-->
<!-- if (!isCallable(mapFn)) {-->
<!-- throw new TypeError('Array.from: when provided, the second argument must be a function');-->
<!-- }-->
<!-- // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.-->
<!-- if (arguments.length > 2) {-->
<!-- T = arguments[2];-->
<!-- }-->
<!-- }-->
<!-- // 10. Let lenValue be Get(items, "length").-->
<!-- // 11. Let len be ToLength(lenValue).-->
<!-- var len = toLength(items.length);-->
<!-- // 13. If IsConstructor(C) is true, then-->
<!-- // 13. a. Let A be the result of calling the [[Construct]] internal method-->
<!-- // of C with an argument list containing the single item len.-->
<!-- // 14. a. Else, Let A be ArrayCreate(len).-->
<!-- var A = isCallable(C) ? Object(new C(len)) : new Array(len);-->
<!-- // 16. Let k be 0.-->
<!-- var k = 0;-->
<!-- // 17. Repeat, while k < len… (also steps a - h)-->
<!-- var kValue;-->
<!-- while (k < len) {-->
<!-- kValue = items[k];-->
<!-- if (mapFn) {-->
<!-- A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);-->
<!-- } else {-->
<!-- A[k] = kValue;-->
<!-- }-->
<!-- k += 1;-->
<!-- }-->
<!-- // 18. Let putStatus be Put(A, "length", len, true).-->
<!-- A.length = len;-->
<!-- // 20. Return A.-->
<!-- return A;-->
<!-- };-->
<!-- }());-->
<!-- }-->
<!-- </script>-->
<!-- very, very dirty hack to correct the URL for calls to "/config.xml" from the confighelper.js/cordova.js in the cordova-browser package -->
<script type="text/javascript">
const open = XMLHttpRequest.prototype.open;
......
......@@ -65,6 +65,7 @@ import 'zone.js/dist/zone'; // Included with Angular CLI.
* APPLICATION IMPORTS
*/
// polyfills for IE 11
import 'core-js/es6/object';
import 'core-js/es6/set';
import 'core-js/es6/array';
import 'core-js/es6/symbol';
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment