JS -- Fix doc.getField and add missing field methods
- getField("foo") was wrongly returning a field named "foobar";
 - field object had few missing unimplemented methods
			
			
This commit is contained in:
		
							parent
							
								
									952bc08ec0
								
							
						
					
					
						commit
						82f75a8ac2
					
				@ -828,8 +828,26 @@ class Doc extends PDFObject {
 | 
			
		||||
      return searchedField;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const parts = cName.split("#");
 | 
			
		||||
    let childIndex = NaN;
 | 
			
		||||
    if (parts.length === 2) {
 | 
			
		||||
      childIndex = Math.floor(parseFloat(parts[1]));
 | 
			
		||||
      cName = parts[0];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (const [name, field] of this._fields.entries()) {
 | 
			
		||||
      if (name.includes(cName)) {
 | 
			
		||||
      if (name.endsWith(cName)) {
 | 
			
		||||
        if (!isNaN(childIndex)) {
 | 
			
		||||
          const children = this._getChildren(name);
 | 
			
		||||
          if (childIndex < 0 || childIndex >= children.length) {
 | 
			
		||||
            childIndex = 0;
 | 
			
		||||
          }
 | 
			
		||||
          if (childIndex < children.length) {
 | 
			
		||||
            this._fields.set(cName, children[childIndex]);
 | 
			
		||||
            return children[childIndex];
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        this._fields.set(cName, field);
 | 
			
		||||
        return field;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@ -837,6 +855,23 @@ class Doc extends PDFObject {
 | 
			
		||||
    return undefined;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _getChildren(fieldName) {
 | 
			
		||||
    // Children of foo.bar are foo.bar.oof, foo.bar.rab
 | 
			
		||||
    // but not foo.bar.oof.FOO.
 | 
			
		||||
    const len = fieldName.length;
 | 
			
		||||
    const children = [];
 | 
			
		||||
    const pattern = /^\.[^.]+$/;
 | 
			
		||||
    for (const [name, field] of this._fields.entries()) {
 | 
			
		||||
      if (name.startsWith(fieldName)) {
 | 
			
		||||
        const finalPart = name.slice(len);
 | 
			
		||||
        if (finalPart.match(pattern)) {
 | 
			
		||||
          children.push(field);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return children;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getIcon() {
 | 
			
		||||
    /* Not implemented */
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@ class Field extends PDFObject {
 | 
			
		||||
    this.doNotSpellCheck = data.doNotSpellCheck;
 | 
			
		||||
    this.delay = data.delay;
 | 
			
		||||
    this.display = data.display;
 | 
			
		||||
    this.doc = data.doc;
 | 
			
		||||
    this.doc = data.doc.wrapped;
 | 
			
		||||
    this.editable = data.editable;
 | 
			
		||||
    this.exportValues = data.exportValues;
 | 
			
		||||
    this.fileSelect = data.fileSelect;
 | 
			
		||||
@ -68,8 +68,13 @@ class Field extends PDFObject {
 | 
			
		||||
 | 
			
		||||
    // Private
 | 
			
		||||
    this._actions = createActionsMap(data.actions);
 | 
			
		||||
    this._browseForFileToSubmit = data.browseForFileToSubmit || null;
 | 
			
		||||
    this._buttonCaption = null;
 | 
			
		||||
    this._buttonIcon = null;
 | 
			
		||||
    this._children = null;
 | 
			
		||||
    this._currentValueIndices = data.currentValueIndices || 0;
 | 
			
		||||
    this._document = data.doc;
 | 
			
		||||
    this._fieldPath = data.fieldPath;
 | 
			
		||||
    this._fillColor = data.fillColor || ["T"];
 | 
			
		||||
    this._isChoice = Array.isArray(data.items);
 | 
			
		||||
    this._items = data.items || [];
 | 
			
		||||
@ -197,6 +202,48 @@ class Field extends PDFObject {
 | 
			
		||||
    this._valueAsString = val ? val.toString() : "";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  browseForFileToSubmit() {
 | 
			
		||||
    if (this._browseForFileToSubmit) {
 | 
			
		||||
      // TODO: implement this function on Firefox side
 | 
			
		||||
      // we can use nsIFilePicker but open method is async.
 | 
			
		||||
      // Maybe it's possible to use a html input (type=file) too.
 | 
			
		||||
      this._browseForFileToSubmit();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  buttonGetCaption(nFace = 0) {
 | 
			
		||||
    if (this._buttonCaption) {
 | 
			
		||||
      return this._buttonCaption[nFace];
 | 
			
		||||
    }
 | 
			
		||||
    return "";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  buttonGetIcon(nFace = 0) {
 | 
			
		||||
    if (this._buttonIcon) {
 | 
			
		||||
      return this._buttonIcon[nFace];
 | 
			
		||||
    }
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  buttonImportIcon(cPath = null, nPave = 0) {
 | 
			
		||||
    /* Not implemented */
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  buttonSetCaption(cCaption, nFace = 0) {
 | 
			
		||||
    if (!this._buttonCaption) {
 | 
			
		||||
      this._buttonCaption = ["", "", ""];
 | 
			
		||||
    }
 | 
			
		||||
    this._buttonCaption[nFace] = cCaption;
 | 
			
		||||
    // TODO: send to the annotation layer
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  buttonSetIcon(oIcon, nFace = 0) {
 | 
			
		||||
    if (!this._buttonIcon) {
 | 
			
		||||
      this._buttonIcon = [null, null, null];
 | 
			
		||||
    }
 | 
			
		||||
    this._buttonIcon[nFace] = oIcon;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  checkThisBox(nWidget, bCheckIt = true) {}
 | 
			
		||||
 | 
			
		||||
  clearItems() {
 | 
			
		||||
@ -260,6 +307,17 @@ class Field extends PDFObject {
 | 
			
		||||
    return bExportValue ? item.exportValue : item.displayValue;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getArray() {
 | 
			
		||||
    if (this._children === null) {
 | 
			
		||||
      this._children = this._document.obj._getChildren(this._fieldPath);
 | 
			
		||||
    }
 | 
			
		||||
    return this._children;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getLock() {
 | 
			
		||||
    return undefined;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  isBoxChecked(nWidget) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
@ -337,6 +395,20 @@ class Field extends PDFObject {
 | 
			
		||||
    this._send({ id: this._id, items: this._items });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  setLock() {}
 | 
			
		||||
 | 
			
		||||
  signatureGetModifications() {}
 | 
			
		||||
 | 
			
		||||
  signatureGetSeedValue() {}
 | 
			
		||||
 | 
			
		||||
  signatureInfo() {}
 | 
			
		||||
 | 
			
		||||
  signatureSetSeedValue() {}
 | 
			
		||||
 | 
			
		||||
  signatureSign() {}
 | 
			
		||||
 | 
			
		||||
  signatureValidate() {}
 | 
			
		||||
 | 
			
		||||
  _isButton() {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,8 @@ function initSandbox(params) {
 | 
			
		||||
      const obj = objs[0];
 | 
			
		||||
      obj.send = send;
 | 
			
		||||
      obj.globalEval = globalEval;
 | 
			
		||||
      obj.doc = _document.wrapped;
 | 
			
		||||
      obj.doc = _document;
 | 
			
		||||
      obj.fieldPath = name;
 | 
			
		||||
      let field;
 | 
			
		||||
      if (obj.type === "radiobutton") {
 | 
			
		||||
        const otherButtons = objs.slice(1);
 | 
			
		||||
 | 
			
		||||
@ -161,6 +161,64 @@ describe("Scripting", function () {
 | 
			
		||||
        done.fail(ex);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("should get field using a path", async function (done) {
 | 
			
		||||
      const base = value => {
 | 
			
		||||
        return {
 | 
			
		||||
          id: getId(),
 | 
			
		||||
          value,
 | 
			
		||||
          actions: {},
 | 
			
		||||
          type: "text",
 | 
			
		||||
        };
 | 
			
		||||
      };
 | 
			
		||||
      const data = {
 | 
			
		||||
        objects: {
 | 
			
		||||
          A: [base(1)],
 | 
			
		||||
          "A.B": [base(2)],
 | 
			
		||||
          "A.B.C": [base(3)],
 | 
			
		||||
          "A.B.C.D": [base(4)],
 | 
			
		||||
          "A.B.C.D.E": [base(5)],
 | 
			
		||||
          "A.B.C.D.E.F": [base(6)],
 | 
			
		||||
          "A.B.C.D.G": [base(7)],
 | 
			
		||||
          C: [base(8)],
 | 
			
		||||
        },
 | 
			
		||||
        appInfo: { language: "en-US", platform: "Linux x86_64" },
 | 
			
		||||
        calculationOrder: [],
 | 
			
		||||
        dispatchEventName: "_dispatchMe",
 | 
			
		||||
      };
 | 
			
		||||
      sandbox.createSandbox(data);
 | 
			
		||||
 | 
			
		||||
      try {
 | 
			
		||||
        await myeval(`this.getField("A").value`).then(value => {
 | 
			
		||||
          expect(value).toEqual(1);
 | 
			
		||||
        });
 | 
			
		||||
        await myeval(`this.getField("B.C").value`).then(value => {
 | 
			
		||||
          expect(value).toEqual(3);
 | 
			
		||||
        });
 | 
			
		||||
        // path has been cached so try again
 | 
			
		||||
        await myeval(`this.getField("B.C").value`).then(value => {
 | 
			
		||||
          expect(value).toEqual(3);
 | 
			
		||||
        });
 | 
			
		||||
        await myeval(`this.getField("B.C.D#0").value`).then(value => {
 | 
			
		||||
          expect(value).toEqual(5);
 | 
			
		||||
        });
 | 
			
		||||
        await myeval(`this.getField("B.C.D#1").value`).then(value => {
 | 
			
		||||
          expect(value).toEqual(7);
 | 
			
		||||
        });
 | 
			
		||||
        await myeval(`this.getField("C").value`).then(value => {
 | 
			
		||||
          expect(value).toEqual(8);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        await myeval(
 | 
			
		||||
          `this.getField("A.B.C.D").getArray().map((x) => x.value)`
 | 
			
		||||
        ).then(value => {
 | 
			
		||||
          expect(value).toEqual([5, 7]);
 | 
			
		||||
        });
 | 
			
		||||
        done();
 | 
			
		||||
      } catch (ex) {
 | 
			
		||||
        done.fail(ex);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe("Util", function () {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user