3

我尝试npm install htmlparser2在 SmartMobileStudio 中使用 htmlparser2 模块(通过 安装)。该模块本身在直接 javascript 中运行良好(使用htmlparser2 的 Homepage中稍作更改的示例):

var htmlparser = require("htmlparser2");
var parser = new htmlparser.Parser({
    onopentag: function(name, attribs){
        console.log(name);
        console.log(attribs);
    }
});
parser.write("<img src='image1.jpg'>");
parser.end();

使用 SMS (2.0.0.9 Beta) 我尝试像这样导入模块:

unit NodeJS.htmlparser2;

interface

uses
  NodeJS.Core,
  NodeJS.events;

type
  TOnTag = procedure(name: string; attribs: Variant);
  TOnText = procedure(text: string);

  JParser = class external(NodeJS.events.JNodeEventEmitter)
    procedure write(s: string);
    procedure &end;
  end;

  Jhtmlparser_Exports = class external
  public
    function Parser(onopentag: TOnTag; ontext: TOnText; onclosetag: TOnTag): JParser;
  end;

function htmlparser2: Jhtmlparser_Exports;

implementation

function htmlparser2: Jhtmlparser_Exports;
begin
  result := Jhtmlparser_Exports( require("htmlparser2") );
end;

end.

我更改了 Node.js-New-Project-Template 生成的项目,如下所示:

[...]

procedure TServer.Run;
begin
  var htmlparser := NodeJS.htmlparser2.htmlparser2;

  var parser := htmlparser.Parser(
   procedure (Name: string; Attribs: Variant)
   begin
     console_.log([Name]);
     console_.log([Attribs]);
   end,
   nil,
   nil);

  parser.write("<img src='image1.jpg'>");
  parser.end();
end;

问题是发出的代码不正确,但几乎是:

[...]
parser = htmlparser.Parser(function (Name$3, Attribs) {
   console_().log([Name$3].slice());
   console_().log([Attribs].slice());
},null,null);
[...]

这有效:

[...]
parser = new htmlparser.Parser({onopentag: function (Name$3, Attribs) {
   console_().log([Name$3].slice());
   console_().log([Attribs].slice());
}});
[...]

区别在于“new”关键字和命名事件回调“onopentag”。我需要写什么来生成有效的 js 代码?

4

2 回答 2

3

因为不能像使用 javascript 和 requirejs/nodejs 那样在 pascal 中“导出”类,所以我们需要使用外部类技巧:我们可以为外部类名称设置一些代码。其次,我们需要提供一个“选项”对象(更详细但需要类型安全)。

JParserOptions = class
  onopentag : TOnTag;
  ontext    : TOnText;
  onclosetag: TOnTag
end;

JParser = class external '(htmlparser2()).Parser' (NodeJS.events.JNodeEventEmitter)
  constructor Create(options: JParserOptions);

  procedure write(s: string);
  procedure &end;
end;

我们可以这样使用它:

var options = JParserOptions.Create;
options.onopentag := procedure (Name: string; Attribs: Variant)
  begin
    console_.log([Name]);
    console_.log([Attribs]);
  end;

var parser := new JParser(options);
于 2013-12-30T20:35:58.590 回答
2

顺便说一句,我找到了一个更好的解决方案:使用类引用(JParserClass = JParser 的类)

  JParser = class external(NodeJS.events.JNodeEventEmitter)
    constructor Create(onopentag: TOnTag; ontext: TOnText; onclosetag: TOnTag);
    procedure write(s: string);
    procedure &end;
  end;
  JParserClass = class of JParser;

  Jhtmlparser_Exports = class external
  public
    Parser: JParserClass;
  end;

然后你可以像这样创建类:

  var parser := new (htmlparser2.Parser)(

或者像这样:

  var parserclass = htmlparser2.Parser;
  var parser := new parserclass(

或者:

  var parserclass = htmlparser2.Parser;
  var parser := parserclass.Create(
于 2014-01-07T12:12:52.057 回答