import {ElementRef, Component, Input, Output, OnInit, EventEmitter,
AfterViewInit, Renderer2} from '@angular/core';
import {filter} from 'rxjs/operators';
-import {MarcRecord, MarcField} from './marcrecord';
+import {MarcRecord, MarcField, MarcSubfield} from './marcrecord';
import {MarcEditContext, FieldFocusRequest} from './editor-context';
/**
@Input() fieldText: string = null;
// array of subfield code and subfield value
- @Input() subfield: string[]; // [code, value]
+ @Input() subfield: MarcSubfield;
// space-separated list of additional CSS classes to append
@Input() moreClasses: string;
).subscribe((req: FieldFocusRequest) => {
if (req.sfOffset !== undefined &&
- req.sfOffset !== Number(this.subfield[2])) {
+ req.sfOffset !== this.subfield[2]) {
// subfield focus request, but we are not this subfield
return;
}
focusBigText() {
const targetNode = this.editInput.firstChild;
+ if (!targetNode) {
+ // Div contains no text content, nothing to select
+ return;
+ }
+
const range = document.createRange();
range.setStart(targetNode, 0);
range.setEnd(targetNode, targetNode.length);
case 'Delete': return this.keyDelete(evt);
case 'ArrowDown': return this.keyArrowDown(evt);
case 'ArrowUp': return this.keyArrowUp(evt);
- case 'F6': return this.keyF6(evt);
- case 'F7': return this.keyF7(evt);
- case 'F8': return this.keyF8(evt);
+
+ case 'F6':
+ if (evt.shiftKey) {
+ // shift+F6 => add 006
+ this.context.add006();
+ evt.preventDefault();
+ evt.stopPropagation();
+ }
+ break;
+
+ case 'F7':
+ if (evt.shiftKey) {
+ // shift+F7 => add 007
+ this.context.add007();
+ evt.preventDefault();
+ evt.stopPropagation();
+ }
+ break;
+
+ case 'F8':
+ if (evt.shiftKey) {
+ // shift+F8 => add/replace 008
+ this.context.insertReplace008();
+ evt.preventDefault();
+ evt.stopPropagation();
+ }
+ break;
+
+ case 'd': // thunk
+ case 'i':
+ if (evt.ctrlKey) {
+ // ctrl+i / ctrl+d == insert subfield
+ const pos = this.subfield ? this.subfield[2] + 1 : 0;
+ this.context.insertSubfield(this.field, pos);
+ evt.preventDefault();
+ }
+ break;
+
}
}
if (evt.ctrlKey) {
- const newField = this.context.record.newField(
- {tag: '999', subfields: [[' ', '', '0']]});
+ const newField = this.record.newField(
+ {tag: '999', subfields: [[' ', '', 0]]});
if (evt.shiftKey) {
- this.context.record.insertFieldsBefore(this.field, newField);
+ this.record.insertFieldsBefore(this.field, newField);
} else {
- this.context.record.insertFieldsAfter(this.field, newField);
+ this.record.insertFieldsAfter(this.field, newField);
}
this.context.requestFieldFocus(
// If subfields remain, focus the previous subfield.
// otherwise focus our tag.
- const sfpos = Number(this.subfield[2]) - 1;
+ const sfpos = this.subfield[2] - 1;
this.field.deleteExactSubfields(this.subfield);
if (evt.ctrlKey) { // Copy field down
- this.context.record.insertFieldsAfter(
- this.field,
- this.context.record.cloneField(this.field)
- );
+ this.record.insertFieldsAfter(
+ this.field, this.record.cloneField(this.field));
}
const field = this.record.getNextField(this.field.fieldId);
if (evt.ctrlKey) {
- this.context.record.insertFieldsBefore(
- this.field,
- this.context.record.cloneField(this.field)
- );
+ this.record.insertFieldsBefore(
+ this.field, this.record.cloneField(this.field));
}
const field = this.record.getPreviousField(this.field.fieldId);
evt.preventDefault();
}
-
- keyF6(evt: KeyboardEvent) {
- console.log('f6');
-
- if (evt.shiftKey) {
-
- evt.preventDefault();
- evt.stopPropagation();
- }
- }
-
- keyF7(evt: KeyboardEvent) {
- console.log('f7');
-
- if (evt.shiftKey) {
-
- evt.preventDefault();
- evt.stopPropagation();
- }
- }
-
- keyF8(evt: KeyboardEvent) {
- console.log('f8');
-
- if (evt.shiftKey) {
- evt.preventDefault();
- evt.stopPropagation();
- }
- }
}
import {EventEmitter} from '@angular/core';
-import {MarcRecord, MarcField} from './marcrecord';
+import {MarcRecord, MarcField, MarcSubfield} from './marcrecord';
import {NgbPopover} from '@ng-bootstrap/ng-bootstrap';
/* Per-instance MARC editor context. */
// focus request is emitted.
setTimeout(() => this.fieldFocusRequest.emit(req));
}
+
+ add006() {
+ this.record.insertOrderedFields(
+ this.record.newField({
+ tag : '006',
+ data : ' '
+ })
+ );
+ }
+
+
+ add007() {
+ this.record.insertOrderedFields(
+ this.record.newField({
+ tag : '007',
+ data : ' '
+ })
+ );
+ }
+
+ insertReplace008() {
+
+ // delete all of the 008s
+ [].concat(this.record.field('008', true)).forEach(
+ f => this.record.deleteFields(f));
+
+ // add a new 008
+ this.record.insertOrderedFields(
+ this.record.newField({
+ tag : '008',
+ data : this.record.generate008()
+ })
+ );
+ }
+
+ // Adds a new empty subfield to the provided field at the
+ // requested subfield position
+ insertSubfield(field: MarcField, position: number) {
+
+ // array index 3 contains that position of the subfield
+ // in the MARC field. When splicing a new subfield into
+ // the set, be sure the any that come after the new one
+ // have their positions bumped to reflect the shift.
+ field.subfields.forEach(
+ sf => {if (sf[2] >= position) { sf[2]++; }});
+
+ const newSf: MarcSubfield = [' ', '', position];
+ field.subfields.splice(position, 0, newSf);
+
+ this.requestFieldFocus({
+ fieldId: field.fieldId,
+ target: 'sfc',
+ sfOffset: position
+ });
+ }
}
// MARC breaker delimiter
const DELIMITER = '$';
-// This acts as a veneer over a Marc.Field object.
+export interface MarcSubfield // code, value, position
+ extends Array<string|number>{0: string; 1: string; 2: number}
+
+// Only contains the attributes/methods we need so far.
export interface MarcField {
fieldId?: number;
data?: string;
tag?: string;
ind1?: string;
ind2?: string;
-
- // [[sfCode, sfValue], [sfCode, sfValue], ...]
- subfields?: string[][];
+ subfields?: MarcSubfield[];
isControlfield(): boolean;
- deleteExactSubfields(subfields: string[]): number;
+ deleteExactSubfields(...subfield: MarcSubfield[]): number;
}
export class MarcRecord {
}
}
+ field(spec: string, wantArray?: boolean): MarcField | MarcField[] {
+ return this.record.field(spec, wantArray);
+ }
+
insertFieldsBefore(field: MarcField, ...newFields: MarcField[]) {
this.record.insertFieldsBefore.apply(
this.record, [field].concat(newFields));
this.stampFieldIds();
}
+ insertOrderedFields(...newFields: MarcField[]) {
+ this.record.insertOrderedFields.apply(this.record, newFields);
+ this.stampFieldIds();
+ }
+
+ generate008(): MarcField {
+ return this.record.generate008();
+ }
+
+
deleteFields(...fields: MarcField[]) {
this.record.deleteFields.apply(this.record, fields);
}
return this.newField(props);
}
- cloneSubfields(subfields: string[][]): string[][] {
+ cloneSubfields(subfields: MarcSubfield[]): MarcSubfield[] {
const root = [];
subfields.forEach(sf => root.push([].concat(sf)));
return root;