From f08331a56c58b525437eeafdbdbf36b94c5193c3 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Thu, 21 Jun 2018 13:06:29 -0400 Subject: [PATCH] LP#1775466 more legacy parser; printing; cleanup Signed-off-by: Bill Erickson --- Open-ILS/src/eg2/src/app/app.module.ts | 5 +- Open-ILS/src/eg2/src/app/common.module.ts | 4 +- .../eg2/src/app/share/catalog/search-context.ts | 2 +- Open-ILS/src/eg2/src/app/share/grid/grid.ts | 8 +-- .../src/eg2/src/app/share/print/print.component.ts | 75 +++++++++------------- .../src/eg2/src/app/share/print/print.service.ts | 5 +- Open-ILS/src/eg2/src/app/staff/common.module.ts | 2 + .../eg2/src/app/staff/sandbox/sandbox.component.ts | 18 ++---- .../share/legacy-template.service.ts} | 46 +++++++------ 9 files changed, 71 insertions(+), 94 deletions(-) rename Open-ILS/src/eg2/src/app/{share/util/parser.service.ts => staff/share/legacy-template.service.ts} (89%) diff --git a/Open-ILS/src/eg2/src/app/app.module.ts b/Open-ILS/src/eg2/src/app/app.module.ts index 1f22babfe5..20de8ab017 100644 --- a/Open-ILS/src/eg2/src/app/app.module.ts +++ b/Open-ILS/src/eg2/src/app/app.module.ts @@ -1,7 +1,7 @@ /** * BaseModule is the shared starting point for all apps. It provides - * the root route and core services, and a simple welcome page for users - * that end up here accidentally. + * the root route and a simple welcome page for users that end up here + * accidentally. */ import {BrowserModule} from '@angular/platform-browser'; import {NgModule} from '@angular/core'; @@ -13,7 +13,6 @@ import {BaseComponent} from './app.component'; import {BaseRoutingModule} from './routing.module'; import {WelcomeComponent} from './welcome.component'; -// Import and 'provide' globally required services. @NgModule({ declarations: [ BaseComponent, diff --git a/Open-ILS/src/eg2/src/app/common.module.ts b/Open-ILS/src/eg2/src/app/common.module.ts index dd3c201fff..e04e00309e 100644 --- a/Open-ILS/src/eg2/src/app/common.module.ts +++ b/Open-ILS/src/eg2/src/app/common.module.ts @@ -17,7 +17,6 @@ import {PcrudService} from '@eg/core/pcrud.service'; import {OrgService} from '@eg/core/org.service'; import {AudioService} from '@eg/share/util/audio.service'; import {FormatService} from '@eg/share/util/format.service'; -import {TemplateParserService} from '@eg/share/util/parser.service'; import {PrintService} from '@eg/share/print/print.service'; // Globally available components @@ -73,8 +72,7 @@ export class EgCommonModule { OrgService, PrintService, AudioService, - FormatService, - TemplateParserService + FormatService ] }; } diff --git a/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts b/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts index 7b918ca6b7..e4e64b2d0e 100644 --- a/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts +++ b/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts @@ -39,7 +39,7 @@ export class CatalogSearchContext { sort: string; fieldClass: string[]; query: string[]; - identQuery: string; + identQuery: string; identQueryType: string; // isbn, issn, etc. joinOp: string[]; matchOp: string[]; diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid.ts b/Open-ILS/src/eg2/src/app/share/grid/grid.ts index 876c2e97eb..3a967a7112 100644 --- a/Open-ILS/src/eg2/src/app/share/grid/grid.ts +++ b/Open-ILS/src/eg2/src/app/share/grid/grid.ts @@ -80,7 +80,7 @@ export class GridColumnSet { } idlInfoFromDotpath(dotpath: string): any { - if (!dotpath) return null; + if (!dotpath) { return null; } let idlParent; let idlField; @@ -95,7 +95,7 @@ export class GridColumnSet { if (idlField) { if (idlField['class'] && ( - idlField.datatype === 'link' || + idlField.datatype === 'link' || idlField.datatype === 'org_unit')) { idlClass = this.idl.classes[idlField['class']]; } @@ -463,7 +463,7 @@ export class GridContext { for (let i = 0; i < steps.length; i++) { const step = steps[i]; - if (typeof obj != 'object') { + if (typeof obj !== 'object') { // We have run out of data to step through before // reaching the end of the path. Conclude fleshing via // callback if provided then exit. @@ -481,7 +481,7 @@ export class GridContext { obj = this.getObjectFieldValue(obj, step); } - // We found a nested IDL object which may or may not have + // We found a nested IDL object which may or may not have // been configured as a top-level column. Flesh the column // metadata with our newly found IDL info. if (idlField) { diff --git a/Open-ILS/src/eg2/src/app/share/print/print.component.ts b/Open-ILS/src/eg2/src/app/share/print/print.component.ts index ad41e5e950..81b8020d91 100644 --- a/Open-ILS/src/eg2/src/app/share/print/print.component.ts +++ b/Open-ILS/src/eg2/src/app/share/print/print.component.ts @@ -1,6 +1,5 @@ import {Component, OnInit, TemplateRef, ElementRef, Renderer2} from '@angular/core'; import {PrintService, PrintRequest} from './print.service'; -import {TemplateParserService} from '@eg/share/util/parser.service'; @Component({ selector: 'eg-print', @@ -12,21 +11,15 @@ export class PrintComponent implements OnInit { // Template that requires local processing template: TemplateRef; - // TemplateParserService-compatible template string. - templateString: string; - // Context data used for processing the template. context: any; + // Insertion point for externally-compiled templates htmlContainer: Element; - // Final HTML print string - htmlResult: string; - constructor( private renderer: Renderer2, private elm: ElementRef, - private parser: TemplateParserService, private printer: PrintService ) {} @@ -34,54 +27,41 @@ export class PrintComponent implements OnInit { this.printer.onPrintRequest$.subscribe( printReq => this.handlePrintRequest(printReq)); - this.htmlContainer = + this.htmlContainer = this.renderer.selectRootElement('#eg-print-container'); } handlePrintRequest(printReq: PrintRequest) { - this.applyTemplate(printReq).then(ok => { - // Give templates a chance to render before printing - setTimeout(() => this.dispatchPrint(printReq)); - }); - } + this.applyTemplate(printReq); - applyTemplate(printReq: PrintRequest): Promise { - return new Promise((resolve, reject) => { + // Give templates a chance to render before printing + setTimeout(() => this.dispatchPrint(printReq)); + } - if (printReq.template) { - // Inline template. Let Angular do the work. - this.template = printReq.template; - this.context = {$implicit: printReq.contextData}; - resolve(); - } + applyTemplate(printReq: PrintRequest) { - let promise; - if (printReq.templateString) { + if (printReq.template) { + // Inline template. Let Angular do the interpolationwork. + this.template = printReq.template; + this.context = {$implicit: printReq.contextData}; + return; + } - promise = this.parser.apply( - printReq.templateString, printReq.contextData); + if (printReq.text && true /* !this.hatch.isActive */) { + // Insert HTML into the browser DOM for in-browser printing only. - } else if (printReq.htmlString) { - promise = Promise.resolve(printReq.htmlString); + if (printReq.contentType === 'text/plain') { + // Wrap text/plain content in pre's to prevent + // unintended html formatting. + printReq.text = `
${printReq.text}
`; } - promise.then(html => { - this.htmlResult = html; - - if (true /* !this.hatch.isActive */) { - - // Only insert the HTML into the browser DOM when - // printing locally - this.htmlContainer.innerHTML = this.htmlResult; - } - - resolve(); - }); - }); + this.htmlContainer.innerHTML = printReq.text; + } } dispatchPrint(printReq: PrintRequest) { - if (0 /*this.hatch.isActive*/) { + if (0 /* this.hatch.isActive */) { this.printViaHatch(printReq); } else { // Here the needed HTML is already in the page. @@ -91,16 +71,19 @@ export class PrintComponent implements OnInit { printViaHatch(printReq: PrintRequest) { - if (!this.htmlResult) { - // Sometimes the results come from an externally-parsed HTML + if (!printReq.text) { + // Sometimes the results come from an externally-parsed HTML // template, other times they come from an in-page template. - this.htmlResult = this.elm.nativeElement.innerHTML; + printReq.text = this.elm.nativeElement.innerHTML; } + // Send a full HTML document to Hatch + const html = `${printReq.text}`; + /* this.hatch.print({ printContext: printReq.printContext, - content: this.htmlResult + content: html }); */ } diff --git a/Open-ILS/src/eg2/src/app/share/print/print.service.ts b/Open-ILS/src/eg2/src/app/share/print/print.service.ts index 2825af0fb8..e296720048 100644 --- a/Open-ILS/src/eg2/src/app/share/print/print.service.ts +++ b/Open-ILS/src/eg2/src/app/share/print/print.service.ts @@ -2,11 +2,10 @@ import {Injectable, EventEmitter, TemplateRef} from '@angular/core'; export interface PrintRequest { template?: TemplateRef; - templateString?: string; - templateName?: string; // TODO - htmlString?: string, contextData?: any; + text?: string; printContext: string; + contentType?: string; // defaults to text/html } @Injectable() diff --git a/Open-ILS/src/eg2/src/app/staff/common.module.ts b/Open-ILS/src/eg2/src/app/staff/common.module.ts index 2dfbb3cd8f..98de443fea 100644 --- a/Open-ILS/src/eg2/src/app/staff/common.module.ts +++ b/Open-ILS/src/eg2/src/app/staff/common.module.ts @@ -12,6 +12,7 @@ import {StringComponent} from '@eg/share/string/string.component'; import {StringService} from '@eg/share/string/string.service'; import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component'; import {DateSelectComponent} from '@eg/share/date-select/date-select.component'; +import {LegacyTemplateService} from '@eg/staff/share/legacy-template.service'; /** * Imports the EG common modules and adds modules common to all staff UI's. @@ -51,6 +52,7 @@ export class StaffCommonModule { return { ngModule: StaffCommonModule, providers: [ // Export staff-wide services + LegacyTemplateService, AccessKeyService, StringService, ToastService diff --git a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts index 521db033ca..63bb2fa0de 100644 --- a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts @@ -13,7 +13,7 @@ import {OrgService} from '@eg/core/org.service'; import {Pager} from '@eg/share/util/pager'; import {DateSelectComponent} from '@eg/share/date-select/date-select.component'; import {PrintService} from '@eg/share/print/print.service'; -import {TemplateParserService} from '@eg/share/util/parser.service'; +import {LegacyTemplateService} from '@eg/staff/share//legacy-template.service'; @Component({ templateUrl: 'sandbox.component.html' @@ -55,7 +55,7 @@ export class SandboxComponent implements OnInit { private strings: StringService, private toast: ToastService, private printer: PrintService, - private parser: TemplateParserService + private parser: LegacyTemplateService ) {} ngOnInit() { @@ -177,24 +177,16 @@ export class SandboxComponent implements OnInit { cost: 23.3, copies: [ {barcode: 'abc123', title: 'welcome to the jungle', parts: ['a', 'b', 'c']}, - {barcode: 'def456', title: 'hello mudda, hello fadda', parts: ['x','y']} + {barcode: 'def456', title: 'hello mudda, hello fadda', parts: ['x', 'y']} ] - } + }; - /* this.parser.apply(template, context).then(html => { this.printer.print({ - htmlString: html, + text: html, printContext: 'default' }); }); - */ - - this.printer.print({ - templateString: template, - contextData: context, - printContext: 'default' - }); } } diff --git a/Open-ILS/src/eg2/src/app/share/util/parser.service.ts b/Open-ILS/src/eg2/src/app/staff/share/legacy-template.service.ts similarity index 89% rename from Open-ILS/src/eg2/src/app/share/util/parser.service.ts rename to Open-ILS/src/eg2/src/app/staff/share/legacy-template.service.ts index 165866d9cf..fbd6265f5f 100644 --- a/Open-ILS/src/eg2/src/app/share/util/parser.service.ts +++ b/Open-ILS/src/eg2/src/app/staff/share/legacy-template.service.ts @@ -1,8 +1,10 @@ /** + * USING EVAL() OPENS A LARGE SECURITY HOLE. + * DEPRECATE ME. * AngularJS-style minimal template parser. * Original use case is supporting AngularJS style print templates. - * Template context data is applied only once at parsing time, there - * is no Angular-style data binding. + * Template context data is applied only once at parsing time, there + * is no data binding. * * Supports the following template constructs: * {{variables}} @@ -26,7 +28,7 @@ class ParserInstance { } // Given an HTML string and an interpolation context/scope, - // process the HTML template declarations, apply variable + // process the HTML template declarations, apply variable // replacements, and return the restulting HTML string. parse(html: string, context: any): string { @@ -34,7 +36,7 @@ class ParserInstance { this.context = Object.assign({}, context); const parser = new DOMParser(); - const doc = parser.parseFromString(html, "text/html"); + const doc = parser.parseFromString(html, 'text/html'); // Parsing as html wraps the content in an wrapper const domNode = doc.getElementsByTagName('body')[0]; @@ -46,7 +48,7 @@ class ParserInstance { // Process each node in the in-progress document. traverse(node: Node) { - if (!node) return; + if (!node) { return; } switch (node.nodeType) { case Node.ELEMENT_NODE: @@ -66,7 +68,7 @@ class ParserInstance { } // Process expressions found on each element. - // Returns true if the node was processed within and needs no + // Returns true if the node was processed within and needs no // further processing, false otherwise. processElementNode(node: Element): boolean { @@ -99,8 +101,8 @@ class ParserInstance { return false; } - // Returns true if any of the switch expressions resulted - // in true, thus allowing a child node to remain and require + // Returns true if any of the switch expressions resulted + // in true, thus allowing a child node to remain and require // future processing. processSwitchExpression(node: Element, expr: string): boolean { @@ -170,7 +172,7 @@ class ParserInstance { // To evaluate free-form expressions, create an environment // where references to elements in the context are available. - // For example: ng-if="foo.bar" -- the 'foo' key from the + // For example: ng-if="foo.bar" -- the 'foo' key from the // context must be defined in advance for evaluation to succeed. generateEvalEnv() { let env = ''; @@ -180,18 +182,18 @@ class ParserInstance { return env; } - // Returns true of the IF expression evaluates to true, + // Returns true of the IF expression evaluates to true, // false otherwise. testIfExpression(expr: string): boolean { const env = this.generateEvalEnv(); const evalStr = `${env}; Boolean(${expr})`; - //console.debug('ng-if eval string: ', evalStr); + // console.debug('ng-if eval string: ', evalStr); try { return eval(evalStr); } catch (err) { - //console.debug('IF expression failed with: ', err); + // console.debug('IF expression failed with: ', err); return false; } } @@ -202,12 +204,12 @@ class ParserInstance { if (!node || !node.data) { return; } const matches = node.data.match(/{{.*?}}/g); - if (!matches) { return }; + if (!matches) { return; } matches.forEach(match => { - let dotpath = match.replace(/[{}]/g, ''); + const dotpath = match.replace(/[{}]/g, ''); node.replaceData( - node.data.indexOf(match), + node.data.indexOf(match), match.length, this.getContextStringValue(dotpath) ); @@ -240,7 +242,7 @@ class ParserInstance { // Variable replacements may contain filters. const pieces = dotpath.split('|').map(p => p.trim()); - const path = pieces[0] + const path = pieces[0]; const filter = pieces[1]; const data = { datatype: null, // potentially applied below @@ -250,8 +252,10 @@ class ParserInstance { // TODO: teach the format service about processing due dates. if (filter) { const fParts = filter.split(':').map(p => p.trim()); + const fName = fParts[0]; + const fArgs = fParts.slice(1); - switch (fParts[0]) { + switch (fName) { case 'date': data.datatype = 'timestamp'; break; @@ -259,10 +263,10 @@ class ParserInstance { data.datatype = 'money'; break; case 'limitTo': - const size = fParts[1]; - const offset = fParts[2] || 0; + const size = fArgs[0]; if (size) { - data.value = + const offset = fArgs[1] || 0; + data.value = data.value.substring(offset, offset + size); } break; @@ -275,7 +279,7 @@ class ParserInstance { @Injectable() -export class TemplateParserService { +export class LegacyTemplateService { constructor(private format: FormatService) {} -- 2.11.0