htmlwidgets.pp 80 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2019-Now by Michael Van Canneyt, member of the
  4. Free Pascal development team
  5. WEB Widget Set : Basic bare HTML Widgets
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit htmlwidgets;
  13. {$mode objfpc}
  14. interface
  15. uses
  16. Classes, SysUtils, webwidget, js, web;
  17. Type
  18. TTextMode = (tmText,tmHTML);
  19. { TButtonWidget }
  20. TButtonWidget = Class(TWebWidget)
  21. private
  22. FText: String;
  23. FTextMode: TTextMode;
  24. procedure SetText(AValue: String);
  25. procedure SetTextMode(AValue: TTextMode);
  26. Protected
  27. procedure ApplyText(aElement: TJSHTMLElement);
  28. Procedure SetName(const NewName: TComponentName); override;
  29. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  30. Public
  31. Procedure Click;
  32. Function HTMLTag : String; override;
  33. Published
  34. Property Text : String Read FText Write SetText;
  35. Property TextMode : TTextMode Read FTextMode Write SetTextMode;
  36. end;
  37. { TViewPort }
  38. TViewPort = Class(TCustomWebWidget)
  39. Private
  40. Class var FInstance : TViewPort;
  41. Protected
  42. Class Function FixedParent : TJSHTMLElement; override;
  43. Class Function FixedElement : TJSHTMLElement; override;
  44. Function DoRenderHTML(aParent,aElement : TJSHTMLElement) :TJSHTMLElement; override;
  45. Public
  46. Constructor Create (aOwner: TComponent); override;
  47. Function HTMLTag : String; override;
  48. Class Function Instance : TViewPort;
  49. Property Element;
  50. end;
  51. { TWebPage }
  52. TWebPage = Class(TCustomWebWidget)
  53. private
  54. Protected
  55. Class Function DefaultParentElement: TJSHTMLElement; override;
  56. Class Function DefaultParent : TCustomWebWidget; override;
  57. Procedure DoUnRender(aParent : TJSHTMLElement) ; override;
  58. Public
  59. Constructor Create(AOwner : TComponent); override;
  60. Function HTMLTag : String; override;
  61. // Later on, allow IFrame;
  62. Published
  63. Property ParentID;
  64. Property ElementID;
  65. Property Classes;
  66. Property Styles;
  67. Property StyleRefresh;
  68. Property Visible;
  69. // Events
  70. Property BeforeRenderHTML;
  71. Property AfterRenderHTML;
  72. Property OnAbort;
  73. Property OnAnimationCancel;
  74. Property OnAnimationEnd;
  75. Property OnAnimationIteration;
  76. Property OnAnimationStart;
  77. Property OnAuxClick;
  78. Property OnBlur;
  79. Property OnCancel;
  80. Property OnCanPlay;
  81. Property OnCanPlayThrough;
  82. Property OnChange;
  83. Property OnClick;
  84. Property OnCompositionEnd;
  85. Property OnCompositionStart;
  86. Property OnCompositionUpdate;
  87. Property OnContextMenu;
  88. Property OnCopy;
  89. Property OnCut;
  90. Property OnCueChange;
  91. Property OnDblClick;
  92. Property OnDurationChange;
  93. Property OnEnded ;
  94. Property OnError ;
  95. Property OnFocus;
  96. Property OnFocusIn ;
  97. Property OnFocusOut ;
  98. Property OnGotPointerCapture;
  99. Property OnInput;
  100. Property OnInvalid;
  101. Property OnKeyDown;
  102. Property OnKeyPress;
  103. Property OnKeyUp;
  104. Property OnLoad;
  105. Property OnLoadedData;
  106. Property OnLoadedMetaData;
  107. Property OnLoadend;
  108. Property OnLoadStart;
  109. Property OnLostPointerCapture;
  110. Property OnMouseDown;
  111. Property OnMouseEnter;
  112. Property OnMouseLeave;
  113. Property OnMouseMove;
  114. Property OnMouseOut;
  115. Property OnMouseUp;
  116. Property OnOverFlow;
  117. Property OnPaste;
  118. Property OnPause;
  119. Property OnPlay;
  120. Property OnPointerCancel;
  121. Property OnPointerDown;
  122. Property OnPointerEnter;
  123. Property OnPointerLeave;
  124. Property OnPointerMove;
  125. Property OnPointerOut;
  126. Property OnPointerOver;
  127. Property OnPointerUp;
  128. Property OnReset;
  129. Property OnResize;
  130. Property OnScroll;
  131. Property OnSelect;
  132. Property OnSubmit;
  133. Property OnTouchStart;
  134. Property OnTransitionCancel;
  135. Property OnTransitionEnd;
  136. Property OnTransitionRun;
  137. Property OnTransitionStart;
  138. Property OnWheel;
  139. end;
  140. { TCustomInputWidget }
  141. TCustomInputWidget = Class(TWebWidget)
  142. private
  143. FValue : String;
  144. FValueName : String;
  145. FText : String;
  146. FReadOnly : Boolean;
  147. FRequired : Boolean;
  148. function GetReadOnly: Boolean;
  149. function GetRequired: Boolean;
  150. function GetText: String;
  151. function GetValue: String;
  152. function GetValueName: String;
  153. procedure SetReadonly(AValue: Boolean);
  154. procedure SetRequired(AValue: Boolean);
  155. procedure SetText(AValue: String);
  156. procedure SetValue(AValue: String);
  157. function GetInputElement: TJSHTMLInputElement;
  158. procedure SetValueName(AValue: String);
  159. Protected
  160. Procedure SetName(const NewName: TComponentName); override;
  161. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  162. Property InputElement : TJSHTMLInputElement Read GetInputElement;
  163. // Text to show (checkbox etc). Enable in descendents as needed
  164. Property Text : String Read GetText Write SetText;
  165. Public
  166. function InputType : String; virtual; abstract;
  167. Function HTMLTag : String; override;
  168. // Value as string
  169. Property Value : String Read GetValue Write SetValue;
  170. // Value Name to use when submitting using form.
  171. Property ValueName : String Read GetValueName Write SetValueName;
  172. Property ReadOnly : Boolean Read GetReadOnly Write SetReadonly;
  173. Property Required : Boolean Read GetRequired Write SetRequired;
  174. end;
  175. { TTextInputWidget }
  176. TInputTextType = (ittText,ittPassword,ittNumber,ittEmail,ittSearch,ittTelephone,ittURL,ittColor);
  177. TTextInputWidget = class(TCustomInputWidget)
  178. private
  179. FMaxLength : Integer;
  180. FMinLength : Integer;
  181. FTextType : TInputTextType;
  182. function GetAsNumber: NativeInt;
  183. function GetMaxLength: NativeInt;
  184. function GetMinLength: NativeInt;
  185. function GetTextType: TInputTextType;
  186. procedure SetAsNumber(AValue: NativeInt);
  187. procedure SetMaxLength(AValue: NativeInt);
  188. procedure SetMinLength(AValue: NativeInt);
  189. procedure SetTextType(AValue: TInputTextType);
  190. Protected
  191. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  192. Public
  193. Class Function AllowChildren : Boolean; override;
  194. function InputType : String; override;
  195. Published
  196. Property Value;
  197. Property ValueName;
  198. Property Required;
  199. Property TextType : TInputTextType Read GetTextType Write SetTextType;
  200. property AsNumber : NativeInt Read GetAsNumber Write SetAsNumber;
  201. Property MaxLength : NativeInt Read GetMaxLength Write SetMaxLength;
  202. Property MinLength : NativeInt Read GetMinLength Write SetMinLength;
  203. // Todo: List support
  204. end;
  205. { TButtonInputWidget }
  206. TInputButtonType = (ibtSubmit,ibtReset,ibtImage);
  207. TInputButtonTypes = set of TInputButtonType;
  208. TButtonInputWidget = class(TCustomInputWidget)
  209. private
  210. FButtonType: TInputButtonType;
  211. FSrc: String;
  212. procedure SetButtonType(AValue: TInputButtonType);
  213. procedure SetSrc(AValue: String);
  214. Public
  215. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  216. function InputType : String; override;
  217. Class Function AllowChildren : Boolean; override;
  218. Published
  219. Property ButtonType : TInputButtonType Read FButtonType Write SetButtonType;
  220. Property Value;
  221. Property ValueName;
  222. Property Src : String Read FSrc Write SetSrc;
  223. end;
  224. { TCheckableInputWidget }
  225. TCheckableInputWidget = class(TCustomInputWidget)
  226. private
  227. FChecked: Boolean;
  228. function GetChecked: Boolean;
  229. procedure SetChecked(AValue: Boolean);
  230. Protected
  231. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  232. Public
  233. Property Value;
  234. Property ValueName;
  235. Property Checked : Boolean Read GetChecked Write SetChecked;
  236. Property Text;
  237. end;
  238. { TRadioInputWidget }
  239. TRadioInputWidget = class(TCheckableInputWidget)
  240. private
  241. Public
  242. function InputType : String; override;
  243. Published
  244. Property Value;
  245. Property ValueName;
  246. Property Checked;
  247. Property Text;
  248. end;
  249. { TCheckboxInputWidget }
  250. TCheckboxInputWidget = class(TCheckableInputWidget)
  251. private
  252. Public
  253. function InputType : String; override;
  254. Published
  255. Property Value;
  256. Property ValueName;
  257. Property Checked;
  258. Property Text;
  259. end;
  260. { TDateInputWidget }
  261. TDateInputWidget = class(TCustomInputWidget)
  262. private
  263. FDate: TDateTime;
  264. function GetDate: TDateTime;
  265. procedure SetDate(AValue: TDateTime);
  266. Public
  267. function InputType : String; override;
  268. Class Function AllowChildren : Boolean; override;
  269. Published
  270. Property Required;
  271. Property ValueName;
  272. Property Date : TDateTime Read GetDate Write SetDate;
  273. end;
  274. { TFileInputWidget }
  275. TFileInfo = record
  276. Name : String;
  277. TimeStamp : TDateTime;
  278. FileType : String;
  279. Size : NativeInt;
  280. end;
  281. TFileInputWidget = class(TCustomInputWidget)
  282. private
  283. FMultiple: Boolean;
  284. function GetFileCount: Integer;
  285. function GetFileDate(aIndex : Integer): TDateTime;
  286. function GetFileInfo(aIndex : Integer): TFileInfo;
  287. function GetFileName(aIndex : Integer): String;
  288. function GetFileSize(aIndex : Integer): NativeInt;
  289. function GetFileType(aIndex : Integer): String;
  290. function GetMultiple: Boolean;
  291. procedure SetMultiple(AValue: Boolean);
  292. Protected
  293. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  294. Public
  295. Class Function AllowChildren : Boolean; override;
  296. function InputType : String; override;
  297. Property FileCount : Integer read GetFileCount;
  298. Property Files[aIndex : Integer] : String Read GetFileName;
  299. Property FileSizes[aIndex : Integer] : NativeInt Read GetFileSize;
  300. Property FileTypes[aIndex : Integer] : String Read GetFileType;
  301. Property FileDates[aIndex : Integer] : TDateTime Read GetFileDate;
  302. Property FileInfos[aIndex : Integer] : TFileInfo Read GetFileInfo;
  303. Published
  304. Property ValueName;
  305. Property Required;
  306. Property Multiple : Boolean Read GetMultiple Write SetMultiple;
  307. end;
  308. { THiddenInputWidget }
  309. THiddenInputWidget = class(TCustomInputWidget)
  310. Public
  311. Class Function AllowChildren : Boolean; override;
  312. function InputType : String; override;
  313. Published
  314. Property ValueName;
  315. Property Value;
  316. Property Required;
  317. end;
  318. { TTextAreaWidget }
  319. TTextAreaWrap = (tawSoft,tawHard,tawOff);
  320. TTextAreaWidget = Class(TWebWidget)
  321. private
  322. FLines: TStrings;
  323. FIgnoreChanges : Boolean;
  324. FMaxLength: Cardinal;
  325. FValueName : String;
  326. FRows,
  327. FColumns : Cardinal;
  328. FWrap: TTextAreaWrap;
  329. FRequired,
  330. FReadOnly : Boolean;
  331. procedure ApplyWrap(aElement: TJSHTMLTextAreaElement);
  332. procedure DoLineChanges(Sender: TObject);
  333. function GetColumns: Cardinal;
  334. function GetLines: TStrings;
  335. function GetReadOnly: Boolean;
  336. function GetRequired: Boolean;
  337. function GetRows: Cardinal;
  338. function GetText: String;
  339. function GetValueName: string;
  340. procedure SetColumns(AValue: Cardinal);
  341. procedure SetLines(AValue: TStrings);
  342. procedure SetMaxLength(AValue: Cardinal);
  343. procedure SetReadonly(AValue: Boolean);
  344. procedure SetRequired(AValue: Boolean);
  345. procedure SetRows(AValue: Cardinal);
  346. procedure SetText(AValue: String);
  347. procedure SetValueName(AValue: string);
  348. Function GetTextArea : TJSHTMLTextAreaElement;
  349. procedure SetWrap(AValue: TTextAreaWrap);
  350. Protected
  351. procedure ApplyLines(aElement: TJSHTMLTextAreaElement);
  352. procedure LinesFromHTML(aHTML : String);
  353. Procedure SetName(const NewName: TComponentName); override;
  354. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  355. Property TextArea :TJSHTMLTextAreaElement Read GetTextArea;
  356. Public
  357. Constructor Create(aOwner : TComponent); override;
  358. Destructor Destroy; override;
  359. Class Function AllowChildren : Boolean; override;
  360. Function HTMLTag : String; override;
  361. Property InnerHTML : String Read GetText Write SetText;
  362. Published
  363. Property ValueName : string Read GetValueName Write SetValueName;
  364. Property Rows : Cardinal Read GetRows Write SetRows;
  365. Property Columns : Cardinal Read GetColumns Write SetColumns;
  366. Property Lines : TStrings Read GetLines Write SetLines;
  367. Property MaxLength : Cardinal Read FMaxLength Write SetMaxLength;
  368. Property Wrap : TTextAreaWrap Read FWrap Write SetWrap;
  369. Property ReadOnly : Boolean Read GetReadOnly Write SetReadonly;
  370. Property Required : Boolean Read GetRequired Write SetRequired;
  371. end;
  372. { TImageWidget }
  373. TImageWidget = class(TWebWidget)
  374. private
  375. FHeight: Integer;
  376. FWidth: Integer;
  377. FSrc : String;
  378. function GetHeight: Integer;
  379. function GetImg: TJSHTMLImageElement;
  380. function GetSrc: String;
  381. function GetWidth: Integer;
  382. procedure SetHeight(AValue: Integer);
  383. procedure SetSrc(AValue: String);
  384. procedure SetWidth(AValue: Integer);
  385. Protected
  386. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  387. Property ImgElement : TJSHTMLImageElement Read GetImg;
  388. Public
  389. Function HTMLTag : String; override;
  390. Published
  391. Property Src : String Read GetSrc Write SetSrc;
  392. Property Width : Integer Read GetWidth Write SetWidth;
  393. Property Height : Integer Read GetHeight Write SetHeight;
  394. end;
  395. { TSelectWidget }
  396. TJSHTMLOptionElementArray = Array of TJSHTMLOptionElement;
  397. TCustomSelectWidget = Class;
  398. { TCustomSelectWidget }
  399. TCustomSelectWidget = class(TWebWidget)
  400. Private
  401. FSize,
  402. FSelectedIndex : Integer;
  403. FOptions : TJSHTMLOptionElementArray;
  404. FMultiple : Boolean;
  405. function GetMultiple: Boolean;
  406. function GetSelected(Index : Integer): Boolean;
  407. function GetSelectedIndex: Integer;
  408. function GetSelect: TJSHTMLSelectElement;
  409. function GetSelectionCount: Integer;
  410. function GetSelectionItem(aIndex : Integer): String;
  411. function GetSelectionValue(aIndex : Integer): String;
  412. function GetSize: Integer;
  413. procedure SetMultiple(AValue: Boolean);
  414. procedure SetSelected(Index : Integer; AValue: Boolean);
  415. procedure SetSelectedIndex(AValue: Integer);
  416. procedure SetSize(AValue: Integer);
  417. Protected
  418. Type
  419. { TSelectOptionEnumerator }
  420. TSelectOptionEnumerator = Class
  421. private
  422. FSelect: TCustomSelectWidget;
  423. public
  424. constructor Create(ASelect : TCustomSelectWidget); reintroduce; virtual;
  425. Function OptionText : String; virtual; abstract;
  426. Function HasValue : boolean; virtual;
  427. Function Value : string; virtual;
  428. function MoveNext: Boolean; virtual; abstract;
  429. Property Select: TCustomSelectWidget Read FSelect;
  430. end;
  431. Protected
  432. function GetItemCount: Integer; virtual;
  433. Function CreateOptionEnumerator : TSelectOptionEnumerator; virtual; abstract;
  434. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  435. Procedure BuildOptions(aSelect : TJSHTMLSelectElement); virtual;
  436. Property Options : TJSHTMLOptionElementArray Read Foptions;
  437. Property SelectElement : TJSHTMLSelectElement Read GetSelect;
  438. Protected
  439. // Can be made public/published
  440. // Items that are selected
  441. Property ItemCount : Integer Read GetItemCount;
  442. Property Selected[Index : Integer] : Boolean Read GetSelected Write SetSelected;
  443. Property SelectionCount : Integer Read GetSelectionCount;
  444. Property SelectionValue[aIndex : Integer] : String Read GetSelectionValue;
  445. Property SelectionItem[aIndex : Integer] : String Read GetSelectionItem;
  446. property SelectedIndex : Integer Read GetSelectedIndex Write SetSelectedindex;
  447. Property Multiple : Boolean Read GetMultiple Write SetMultiple;
  448. Property Size : Integer Read GetSize Write SetSize;
  449. Public
  450. Constructor Create(aOWner : TComponent); override;
  451. Function HTMLTag : String; override;
  452. end;
  453. TSelectWidget = class(TCustomSelectWidget)
  454. private
  455. FItems : TStrings;
  456. FValues : TStrings;
  457. function GetItems: TStrings;
  458. function GetValues: TStrings;
  459. procedure OptionsChanged(Sender: TObject);
  460. procedure setItems(AValue: TStrings);
  461. procedure setValues(AValue: TStrings);
  462. Protected
  463. Type
  464. { TStringsSelectOptionEnumerator }
  465. TStringsSelectOptionEnumerator = Class(TSelectOptionEnumerator)
  466. FCurrent : Integer;
  467. constructor Create(ASelect : TCustomSelectWidget); override;
  468. Function OptionText : String; override;
  469. Function HasValue : boolean; override;
  470. Function Value : string; override;
  471. function MoveNext: Boolean; override;
  472. end;
  473. Function CreateOptionEnumerator: TSelectOptionEnumerator; override;
  474. Public
  475. Constructor Create(aOWner : TComponent); override;
  476. Destructor Destroy; override;
  477. Property SelectionCount;
  478. Property SelectionValue;
  479. Property SelectionItem;
  480. Property Selected;
  481. Property Options;
  482. Property SelectElement;
  483. Property ItemCount;
  484. Published
  485. Property Items : TStrings Read GetItems Write setItems;
  486. Property Values : TStrings Read GetValues Write setValues;
  487. property SelectedIndex;
  488. Property Multiple;
  489. property size;
  490. property Classes;
  491. end;
  492. { TLabelWidget }
  493. TLabelWidget = Class(TWebWidget)
  494. private
  495. FLabelFor: TWebWidget;
  496. FText: String;
  497. function GetLabelEl: TJSHTMLLabelElement;
  498. function GetText: String;
  499. procedure SetLabelFor(AValue: TWebWidget);
  500. procedure SetText(AValue: String);
  501. Protected
  502. procedure ApplyLabelFor(aLabelElement: TJSHTMLLabelElement);
  503. Procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  504. Procedure SetName(const NewName: TComponentName); override;
  505. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  506. Property LabelElement : TJSHTMLLabelElement Read GetLabelEl;
  507. Public
  508. Function HTMLTag : String; override;
  509. Property Text : String Read GetText Write SetText;
  510. Property LabelFor : TWebWidget Read FLabelFor Write SetLabelFor;
  511. end;
  512. TTextTag = (ttParagraph,ttBold,ttItalic,ttUnderline,ttStrikeThrough,ttSpan,ttQuote,ttBlockQuote,ttH1,ttH2,ttH3,ttH4,ttH5,ttH6,ttPre,ttRuby,ttArticle,ttAddress,ttAbbr,ttCustom);
  513. { TTextWidget }
  514. { TCustomTextWidget }
  515. TCustomTextWidget = Class(TCustomWebWidget)
  516. private
  517. FCustomTag: String;
  518. FEnvelopeTag: TTextTag;
  519. FTextMode: TTextMode;
  520. procedure SetCustomTag(AValue: String);
  521. procedure SetEnvelopeTag(AValue: TTextTag);
  522. procedure SetTextMode(AValue: TTextMode);
  523. Protected
  524. procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  525. procedure ApplyText(aElement : TJSHTMLElement); virtual;
  526. Function GetText : String; virtual; abstract;
  527. Public
  528. Function HTMLTag : String; override;
  529. Published
  530. Property CustomTag : String Read FCustomTag Write SetCustomTag;
  531. Property EnvelopeTag : TTextTag Read FEnvelopeTag Write SetEnvelopeTag;
  532. Property TextMode : TTextMode Read FTextMode Write SetTextMode;
  533. end;
  534. TTextWidget = Class(TCustomTextWidget)
  535. private
  536. FText : String;
  537. procedure SetText(AValue: String);
  538. Protected
  539. Function GetText : String; override;
  540. published
  541. Property Text : String Read FText Write SetText;
  542. end;
  543. { TTextLinesWidget }
  544. TTextLinesWidget = Class(TCustomTextWidget)
  545. private
  546. FLines : TStrings;
  547. FForceLineBreaks: Boolean;
  548. procedure DoLinesChanged(Sender: TObject);
  549. procedure SetLines(AValue: TStrings);
  550. procedure SetForceLineBreaks(AValue: Boolean);
  551. Protected
  552. Function GetText : String; override;
  553. procedure ApplyText(aElement : TJSHTMLElement); override;
  554. Public
  555. Constructor Create(aOwner : TComponent); override;
  556. Destructor Destroy; override;
  557. published
  558. Property Lines : TStrings Read FLines Write SetLines;
  559. // When forcelinebreaks is true a <br> will be appended to every line.
  560. // Note that for TextMode=tmText this means the lines will be rendered as-is, but there will still be a <br> between the lines
  561. Property ForceLineBreaks : Boolean Read FForceLineBreaks Write SetForceLineBreaks;
  562. end;
  563. { TCustomTableColumn }
  564. TColumnOption = (coHeader,coCaptionHeader);
  565. TColumnOptions = set of TColumnOption;
  566. TCustomTableColumn = Class(TCollectionItem)
  567. private
  568. FAlignment: TAlignment;
  569. FCaption: String;
  570. FClassNames: String;
  571. procedure SetAlignment(AValue: TAlignment);
  572. procedure SetCaption(AValue: String);
  573. procedure SetClassNames(AValue: String);
  574. Protected
  575. Function RenderColumn : Boolean; virtual;
  576. Function GetDisplayName: string; override;
  577. function GetCaption: String; virtual;
  578. Public
  579. Procedure Assign(Source : TPersistent); override;
  580. Property Alignment : TAlignment Read FAlignment Write SetAlignment;
  581. Property Caption : String Read GetCaption Write SetCaption;
  582. Property ClassNames : String Read FClassNames Write SetClassNames;
  583. end;
  584. { TCustomTableColumns }
  585. TCustomTableColumns = Class(TCollection)
  586. private
  587. function GetCustomColumn(Index : Integer): TCustomTableColumn;
  588. procedure SetCustomColumn(Index : Integer; AValue: TCustomTableColumn);
  589. Protected
  590. Property CustomColumns [Index : Integer] : TCustomTableColumn Read GetCustomColumn Write SetCustomColumn; default;
  591. Public
  592. Function Add(aCaption : String): TCustomTableColumn; overload;
  593. end;
  594. { TCustomTableWidget }
  595. TTableOption = (toHeader, // use THead tag
  596. toHeaderRow, // Create header row
  597. toBody, // use TBody tag
  598. toFooter, // use TFoot tag
  599. toFooterRow, // create footer row
  600. toRowID, // add ID to tr: -kind-row
  601. toCellID, // add ID to cell td: -kind-row-col
  602. toHeaderRowData, // Add rowno to <tr data-row> for header.
  603. toHeaderCellDataRow, // Add rowno to <th data-row> for header. Automatic if onheadercellclick is set.
  604. toHeaderCellDataCol, // Add colno to <th data-col> for header. Automatic if onheadercellclick is set.
  605. toBodyRowData, // Add rowno to <tr data-row> for body.
  606. toBodyCellDataRow, // Add rowno to <th data-row> for body. Automatic if oncellclick is set.
  607. toBodyCellDataCol, // Add colno to <th data-col> for body. Automatic if oncellclick is set.
  608. tofooterRowData, // Add rowno to <tr data-row> for footer
  609. tofooterCellDataRow, // Add rowno to <th data-row> for footer. Automatic if onfootercellclick is set.
  610. tofooterCellDataCol // Add colno to <th data-col> for footer. Automatic if onfootercellclick is set.
  611. );
  612. TTableOptions = Set of TTableOption;
  613. TRowKind = (rkHeader,rkBody,rkFooter);
  614. Type
  615. TCustomTableWidget = Class;
  616. // Constructed only once when rendering !
  617. { TTableWidgetCelldata }
  618. TTableWidgetCellData = Class
  619. private
  620. FAsHTML: Boolean;
  621. FClassNames: String;
  622. FCol: Integer;
  623. FColumn: TCustomTableColumn;
  624. FContent: TJSHTMLElement;
  625. FKind: TRowKind;
  626. FRow: Integer;
  627. FTable: TCustomTableWidget;
  628. FTableID: String;
  629. FTag: String;
  630. FText: String;
  631. FWidget: TWebWidget;
  632. Protected
  633. Procedure SetRowColKind(aRow,aCol : Integer; aKind : TRowKind); virtual;
  634. Procedure Reset; // do not reset row,col, column
  635. Public
  636. Constructor Create(aTable : TCustomTableWidget;aTableID : String); virtual;
  637. Property Table : TCustomTableWidget Read FTable;
  638. Property Column : TCustomTableColumn Read FColumn;
  639. Property Row : Integer Read FRow;
  640. Property Col : Integer Read FCol;
  641. Property Kind : TRowKind Read FKind;
  642. Property Tag : String Read FTag Write FTag;
  643. Property ClassNames : String Read FClassNames Write FClassNames;
  644. Property Text : String Read FText Write FText;
  645. Property AsHTML : Boolean Read FAsHTML Write FAsHTML;
  646. Property Content : TJSHTMLElement Read FContent Write FContent;
  647. Property Widget : TWebWidget Read FWidget Write FWidget;
  648. Property TableID : String Read FTableID;
  649. end;
  650. TTableRowEnumerator = Class
  651. private
  652. FTable: TCustomTableWidget;
  653. FCurrent : Integer;
  654. public
  655. constructor Create(ATable : TCustomTableWidget); reintroduce; virtual;
  656. Procedure GetCellData(aCell : TTableWidgetCellData); virtual;
  657. function MoveNext: Boolean; virtual;
  658. property CurrentRow : Integer Read FCurrent;
  659. Property Table : TCustomTableWidget Read FTable;
  660. end;
  661. TTableRowCountEnumerator = Class (TTableRowEnumerator)
  662. private
  663. FRowCount: Integer;
  664. public
  665. constructor Create(ATable : TCustomTableWidget;aCount : Integer); reintroduce;
  666. function MoveNext: Boolean; override;
  667. Property RowCount : Integer read FRowCount;
  668. end;
  669. TOnCellDataEvent = Procedure (Sender : TObject; Enum : TTableRowEnumerator; aCell : TTableWidgetCellData) of object;
  670. TCustomTableWidget = Class(TCustomWebWidget)
  671. private
  672. FCaption: String;
  673. FColumns: TCustomTableColumns;
  674. FOnCellClick: THTMLNotifyEvent;
  675. FOnFooterCellClick: THTMLNotifyEvent;
  676. FOnFooterRowClick: THTMLNotifyEvent;
  677. FOnHeaderCellClick: THTMLNotifyEvent;
  678. FOnHeaderRowClick: THTMLNotifyEvent;
  679. FOnRowClick: THTMLNotifyEvent;
  680. FTableOptions: TTableOptions;
  681. FOnGetCellData : TOnCellDataEvent;
  682. FWidgets : Array of TWebWidget;
  683. FUpdateCount : Integer;
  684. procedure SetCaption(AValue: String);
  685. procedure SetColumns(AValue: TCustomTableColumns);
  686. procedure SetTableOptions(AValue: TTableOptions);
  687. Protected
  688. procedure AppendCaption(aCaptionElement: TJSHTMLElement); virtual;
  689. procedure RenderData(aElement: TJSHTMLElement); virtual;
  690. function DoCellClick(aEvent: TJSMouseEvent): boolean; virtual;
  691. function DoHeaderCellClick(aEvent: TJSMouseEvent): boolean;virtual;
  692. function DoFooterCellClick(aEvent: TJSMouseEvent): boolean;virtual;
  693. function DoRowClick(aEvent: TJSMouseEvent): boolean; virtual;
  694. function DoHeaderRowClick(aEvent: TJSMouseEvent): boolean;virtual;
  695. function DoFooterRowClick(aEvent: TJSMouseEvent): boolean;virtual;
  696. function CreateColumns: TCustomTableColumns; virtual;
  697. Function DefaultTableOptions: TTableOptions; virtual;
  698. Procedure CreateDefaultColumns; virtual;
  699. Function GetRowEnumerator(aKind : TRowKind) : TTableRowEnumerator; virtual;
  700. function RenderCell(aCell: TTableWidgetCellData): TJSHTMLElement; virtual;
  701. procedure RenderRow(aEnum : TTableRowEnumerator; aParent: TJSHTMLElement; aKind: TRowKind; aCell: TTableWidgetCellData); virtual;
  702. procedure RenderRows(aParent: TJSHTMLElement; aKind : TRowKind; aCell: TTableWidgetCellData); virtual;
  703. Procedure ApplyWidgetSettings(aElement : TJSHTMLElement); override;
  704. Function HTMLTag : String; override;
  705. Function CreateCellData(const aTableID : String) : TTableWidgetCellData; virtual;
  706. Function GetBodyRowEnumerator : TTableRowEnumerator; virtual; abstract;
  707. Protected
  708. // These can be made public/published
  709. Property CustomColumns : TCustomTableColumns Read FColumns Write SetColumns;
  710. Property TableOptions : TTableOptions read FTableOptions write SetTableOptions;
  711. Property Caption : String Read FCaption Write SetCaption;
  712. Property OnGetCellData : TOnCellDataEvent Read FOnGetCellData Write FOnGetCellData;
  713. Property OnCellClick : THTMLNotifyEvent Read FOnCellClick Write FOnCellClick;
  714. Property OnHeaderCellClick : THTMLNotifyEvent Read FOnHeaderCellClick Write FOnHeaderCellClick;
  715. Property OnFooterCellClick : THTMLNotifyEvent Read FOnFooterCellClick Write FOnFooterCellClick;
  716. Property OnRowClick : THTMLNotifyEvent Read FOnRowClick Write FOnRowClick;
  717. Property OnHeaderRowClick : THTMLNotifyEvent Read FOnHeaderRowClick Write FOnHeaderRowClick;
  718. Property OnFooterRowClick : THTMLNotifyEvent Read FOnFooterRowClick Write FOnFooterRowClick;
  719. Public
  720. Constructor Create(aOwner : TComponent); override;
  721. Destructor Destroy; override;
  722. Procedure BeginUpdate;
  723. Procedure EndUpdate;
  724. Procedure RefreshBody;
  725. end;
  726. { TEventTableWidget }
  727. TEventTableWidget = Class(TCustomTableWidget)
  728. private
  729. FRowCount: Integer;
  730. procedure SetRowCount(AValue: Integer);
  731. Protected
  732. Function GetBodyRowEnumerator : TTableRowEnumerator; override;
  733. Published
  734. Property RowCount : Integer Read FRowCount Write SetRowCount;
  735. Property CustomColumns;
  736. Property TableOptions;
  737. Property Caption;
  738. Property OnGetCellData;
  739. Property OnCellClick;
  740. Property OnHeaderCellClick;
  741. Property OnFooterCellClick;
  742. Property OnRowClick;
  743. Property OnHeaderRowClick;
  744. Property OnFooterRowClick;
  745. end;
  746. { TCustomStringsTableWidget }
  747. TCustomStringsTableWidget = Class(TCustomTableWidget)
  748. private
  749. Type
  750. TRow = Array of string;
  751. private
  752. FRows : Array of TRow;
  753. function GetRowCount: Integer;
  754. procedure SetRowCount(AValue: Integer);
  755. Protected
  756. Type
  757. TStringRowsEnumerator = Class(TTableRowCountEnumerator)
  758. Procedure GetCellData(aCell : TTableWidgetCellData); override;
  759. end;
  760. Protected
  761. Procedure CheckIndex(aCol,aRow : Integer);
  762. function GetCell(aCol, aRow : integer): String;
  763. procedure SetCell(aCol, aRow : integer; AValue: String);
  764. Function GetBodyRowEnumerator : TTableRowEnumerator; override;
  765. Public
  766. Property RowCount : Integer Read GetRowCount Write SetRowCount;
  767. Property Cells[aCol,aRow : integer] : String Read GetCell Write SetCell;
  768. Property CustomColumns;
  769. Property TableOptions;
  770. Property Caption;
  771. Property OnGetCellData;
  772. Property OnCellClick;
  773. Property OnHeaderCellClick;
  774. Property OnFooterCellClick;
  775. Property OnRowClick;
  776. Property OnHeaderRowClick;
  777. Property OnFooterRowClick;
  778. end;
  779. TStringsTableWidget = Class(TCustomStringsTableWidget)
  780. Published
  781. Property RowCount;
  782. Property CustomColumns;
  783. Property TableOptions;
  784. Property Caption;
  785. Property OnGetCellData;
  786. Property OnCellClick;
  787. Property OnHeaderCellClick;
  788. Property OnFooterCellClick;
  789. Property OnRowClick;
  790. Property OnHeaderRowClick;
  791. Property OnFooterRowClick;
  792. end;
  793. { TDivWidget }
  794. THTMLElementTag = (
  795. etUnknown, eta, etabbr, etacronym, etaddress, etapplet, etarea, etb, etbase,
  796. etbasefont, etbdo, etbig, etblockquote, etbody, etbr, etbutton,
  797. etcaption, etcenter, etcite, etcode, etcol, etcolgroup, etdd, etdel,
  798. etdfn, etdir, etdiv, etdl, etdt, etem, etfieldset, etfont, etform,
  799. etframe, etframeset, eth1, eth2, eth3, eth4, eth5, eth6, ethead, ethr,
  800. ethtml, eti, etiframe, etimg, etinput, etins, etisindex, etkbd, etlabel,
  801. etlegend, etli, etlink, etmap, etmenu, etmeta, etnoframes, etnoscript,
  802. etobject, etol, etoptgroup, etoption, etp, etparam, etpre, etq, ets,
  803. etsamp, etscript, etselect, etsmall, etspan, etstrike, etstrong,
  804. etstyle, etsub, etsup, ettable, ettbody, ettd, ettextarea, ettfoot,
  805. etth, etthead, ettitle, ettr, ettt, etu, etul, etvar,
  806. etText,etAudio,etVideo,etSource
  807. );
  808. THTMLElementTagSet = set of THTMLElementTag;
  809. { TCustomTagWidget }
  810. TCustomTagWidget = Class(TWebWidget)
  811. private
  812. FElementTag: THTMLElementTag;
  813. FTextContent: String;
  814. procedure SetElementTag(AValue: THTMLElementTag);
  815. procedure SetTextContent(AValue: String);
  816. Protected
  817. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  818. Function HTMLTag : String; override;
  819. // Set tag you wish to use
  820. Property elementTag : THTMLElementTag Read FElementTag Write SetElementTag;
  821. // If set, the text will be set as InnerText of the tag
  822. Property TextContent : String Read FTextContent Write SetTextContent;
  823. end;
  824. { TTagWidget }
  825. TTagWidget = Class(TCustomTagWidget)
  826. Public
  827. Constructor Create(aOwner : TComponent); override;
  828. Published
  829. Property elementTag;
  830. Property TextContent;
  831. end;
  832. TDivWidget = Class(TCustomTagWidget)
  833. Public
  834. Constructor Create(aOwner : TComponent); override;
  835. end;
  836. { TParagraphWidget }
  837. TParagraphWidget = Class(TCustomTagWidget)
  838. Public
  839. Constructor Create(aOwner : TComponent); override;
  840. end;
  841. { TMediaWidget }
  842. TMediaWidget = Class(TCustomTagWidget)
  843. private
  844. Const
  845. MaxAttrs = 20;
  846. PropAttrs : Array[0..MaxAttrs] of string
  847. = ('src','defaultPlaybackRate','duration','playbackRate','ended', // 0..4
  848. 'paused','seeking','sinkId','mediaGroup','currentSrc', // 5..9
  849. 'volume','controls','autoplay','crossOrigin', 'defaultMuted', // 10..14
  850. 'currentTime', 'disableRemotePlayback', 'preservesPitch','loop','muted', // 15..19
  851. 'preload' // 20
  852. );
  853. function GetAudioTrack: TJSHTMLAudioTrackList;
  854. function getBool(AIndex: Integer): Boolean;
  855. function GetError: TJSMEdiaError;
  856. function getFloat(AIndex: Integer): Double;
  857. function GetSrcObj: TJSHTMLMediaStream;
  858. function getString(AIndex: Integer): String;
  859. function GetTextTrack: TJSHTMLTextTrackList;
  860. function GetVideoTrack: TJSHTMLVideoTrackList;
  861. procedure SetBool(AIndex: Integer; AValue: Boolean);
  862. procedure SetFloat(AIndex: Integer; AValue: Double);
  863. procedure SetString(AIndex: Integer; AValue: String);
  864. function getEl: TJSObject;
  865. Public
  866. Property DefaultPlayBackRate : Double Index 1 Read getFloat;
  867. Property Duration : Double Index 2 Read getFloat;
  868. Property PlayBackRate : Double Index 3 Read getFloat;
  869. Property Ended : Boolean Index 4 Read getBool;
  870. Property Paused : Boolean Index 5 Read getBool;
  871. Property Seeking : Boolean Index 6 Read getBool;
  872. Property SinkID : String Index 7 Read getString Write SetString;
  873. Property MediaGroup : String Index 8 Read getString Write SetString;
  874. Property SrcObject : TJSHTMLMediaStream Read GetSrcObj;
  875. Property textTracks : TJSHTMLTextTrackList Read GetTextTrack;
  876. Property videoTracks : TJSHTMLVideoTrackList Read GetVideoTrack;
  877. Property audioTracks : TJSHTMLAudioTrackList Read GetAudioTrack;
  878. Property Error : TJSMEdiaError Read GetError;
  879. Property CurrentSrc : String Index 9 Read getString;
  880. Published
  881. Property Src : String Index 0 Read getString Write SetString;
  882. Property Controls : Boolean Index 11 Read getBool Write SetBool;
  883. Property AutoPlay : Boolean Index 12 Read getBool Write SetBool;
  884. Property CrossOrigin : String index 13 Read getString Write SetString;
  885. Property DefaultMuted : Boolean Index 14 Read getBool Write SetBool;
  886. Property CurrentTime : Double Index 15 Read getFloat Write SetFloat;
  887. Property DisableRemotePlayback : Boolean Index 16 Read getBool Write SetBool;
  888. Property PreservesPitch : Boolean Index 17 Read getBool Write SetBool;
  889. Property Loop : Boolean Index 18 Read getBool Write SetBool;
  890. Property Muted : Boolean Index 19 Read getBool Write SetBool;
  891. Property Preload : String Index 20 Read getString Write SetString;
  892. Property Volume : Double Index 10 Read getFloat Write SetFloat;
  893. end;
  894. { TVideoWidget }
  895. TVideoWidget = Class(TMediaWidget)
  896. Public
  897. Constructor Create(aOwner : TComponent); override;
  898. end;
  899. { TAudioWidget }
  900. TAudioWidget = Class(TMediaWidget)
  901. Public
  902. Constructor Create(aOwner : TComponent); override;
  903. end;
  904. Function ViewPort : TViewPort;
  905. Const
  906. TextTagNames : Array[TTextTag] of string
  907. = ('p','b','i','u','s','span','quote','blockquote','h1','h2','h3','h4','h5','h6','pre','ruby','article','address','abbr','');
  908. RowKindNames : Array[TRowKind] of string = ('header','body','footer');
  909. HTMLTagNames : Array[THTMLElementTag] of string = (
  910. '?', 'a', 'abbr', 'acronym', 'address', 'applet', 'area', 'b', 'base',
  911. 'basefont', 'bdo', 'big', 'blockquote', 'body', 'br', 'button',
  912. 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'dd', 'del',
  913. 'dfn', 'dir', 'div', 'dl', 'dt', 'em', 'fieldset', 'font', 'form',
  914. 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr',
  915. 'html', 'i', 'iframe', 'img', 'input', 'ins', 'isindex', 'kbd', 'label',
  916. 'legend', 'li', 'link', 'map', 'menu', 'meta', 'noframes', 'noscript',
  917. 'object', 'ol', 'optgroup', 'option', 'p', 'param', 'pre', 'q', 's',
  918. 'samp', 'script', 'select', 'small', 'span', 'strike', 'strong',
  919. 'style', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot',
  920. 'th', 'thead', 'title', 'tr', 'tt', 'u', 'ul', 'var',
  921. 'Text','Audio','Video','Source'
  922. );
  923. implementation
  924. uses DateUtils;
  925. resourcestring
  926. SErrInvalidIndex = 'Index %d not in valid range of [0..%d]';
  927. SErrInvalidRowCount = 'Invalid row count: %d';
  928. SRow = 'Row';
  929. SCol = 'Column';
  930. Function ViewPort : TViewPort;
  931. begin
  932. Result:=TViewPort.Instance;
  933. end;
  934. { TTableRowCountEnumerator }
  935. Const
  936. CellTags : Array[TRowKind] of string = ('th','td','td');
  937. { TEventTableWidget }
  938. procedure TEventTableWidget.SetRowCount(AValue: Integer);
  939. begin
  940. if FRowCount=AValue then Exit;
  941. BeginUpdate;
  942. FRowCount:=AValue;
  943. EndUpdate;
  944. end;
  945. function TEventTableWidget.GetBodyRowEnumerator: TTableRowEnumerator;
  946. begin
  947. Result:=TTableRowCountEnumerator.Create(Self,RowCount);
  948. end;
  949. { TCustomStringsTableWidget.TStringRowsEnumerator }
  950. procedure TCustomStringsTableWidget.TStringRowsEnumerator.GetCellData(aCell: TTableWidgetCellData);
  951. begin
  952. aCell.Text:=TCustomStringsTableWidget(Table).Cells[aCell.Col,aCell.Row];
  953. end;
  954. { TCustomStringsTableWidget }
  955. function TCustomStringsTableWidget.GetCell(aCol, aRow : integer): String;
  956. begin
  957. CheckIndex(aCol,aRow);
  958. Result:=FRows[aRow][aCol];
  959. end;
  960. function TCustomStringsTableWidget.GetRowCount: Integer;
  961. begin
  962. Result:=Length(FRows);
  963. end;
  964. procedure TCustomStringsTableWidget.SetCell(aCol, aRow : integer; AValue: String);
  965. begin
  966. CheckIndex(aCol,aRow);
  967. BeginUpdate;
  968. try
  969. FRows[aRow][aCol]:=AValue;
  970. Finally
  971. EndUpdate;
  972. end;
  973. end;
  974. function TCustomStringsTableWidget.GetBodyRowEnumerator: TTableRowEnumerator;
  975. begin
  976. Result:=TStringRowsEnumerator.Create(Self,RowCount);
  977. end;
  978. procedure TCustomStringsTableWidget.SetRowCount(AValue: Integer);
  979. begin
  980. if AValue<0 then
  981. raise EWidgets.CreateFmt(SerrInvalidRowCount, [aValue]);
  982. BeginUpdate;
  983. try
  984. SetLength(FRows,aValue);
  985. Finally
  986. EndUpdate;
  987. end;
  988. end;
  989. procedure TCustomStringsTableWidget.CheckIndex(aCol, aRow: Integer);
  990. begin
  991. If (aCol<0) or (aCol>=CustomColumns.Count) then
  992. Raise EWidgets.CreateFmt(SCol+' '+SErrInvalidIndex,[aCol,0,CustomColumns.Count-1]);
  993. If (aRow<0) or (aRow>=RowCount) then
  994. Raise EWidgets.CreateFmt(SRow+' '+SErrInvalidIndex,[aRow,0,RowCount-1]);
  995. end;
  996. { TTagWidget }
  997. constructor TTagWidget.Create(aOwner: TComponent);
  998. begin
  999. inherited Create(aOwner);
  1000. ElementTag:=etdiv;
  1001. end;
  1002. { TMediaWidget }
  1003. function TMediaWidget.GetAudioTrack: TJSHTMLAudioTrackList;
  1004. begin
  1005. if Assigned(Element) then
  1006. Result:=TJSHTMLMediaElement(Element).AudioTracks
  1007. else
  1008. Result:=Nil;
  1009. end;
  1010. function TMediaWidget.getBool(AIndex: Integer): Boolean;
  1011. Var
  1012. El : TJSObject;
  1013. Att : String;
  1014. begin
  1015. El:=GetEl;
  1016. Att:=PropAttrs[aIndex];
  1017. Result:=Assigned(el) and isDefined(El[Att]) and (Boolean(El[Att]));
  1018. end;
  1019. function TMediaWidget.GetError: TJSMEdiaError;
  1020. begin
  1021. If Assigned(Element) then
  1022. Result:=TJSHTMLMediaElement(Element).Error
  1023. else
  1024. Result:=Nil;
  1025. end;
  1026. function TMediaWidget.getFloat(AIndex: Integer): Double;
  1027. Var
  1028. El : TJSObject;
  1029. Att : String;
  1030. begin
  1031. El:=GetEl;
  1032. Att:=PropAttrs[aIndex];
  1033. if Assigned(el) and isDefined(El[Att]) then
  1034. Result:=Double(El[Att])
  1035. else
  1036. Result:=0;
  1037. end;
  1038. function TMediaWidget.GetSrcObj: TJSHTMLMediaStream;
  1039. begin
  1040. If Assigned(Element) then
  1041. Result:=TJSHTMLMediaElement(Element).srcObject
  1042. else
  1043. Result:=Nil;
  1044. end;
  1045. function TMediaWidget.getString(AIndex: Integer): String;
  1046. Var
  1047. El : TJSObject;
  1048. Att : String;
  1049. begin
  1050. El:=GetEl;
  1051. Att:=PropAttrs[aIndex];
  1052. if Assigned(el) and isDefined(El[Att]) then
  1053. Result:=String(El[Att])
  1054. else
  1055. Result:='';
  1056. end;
  1057. function TMediaWidget.GetTextTrack: TJSHTMLTextTrackList;
  1058. begin
  1059. If Assigned(Element) then
  1060. Result:=TJSHTMLMediaElement(Element).TextTracks
  1061. else
  1062. Result:=Nil;
  1063. end;
  1064. function TMediaWidget.GetVideoTrack: TJSHTMLVideoTrackList;
  1065. begin
  1066. If Assigned(Element) then
  1067. Result:=TJSHTMLMediaElement(Element).VideoTracks
  1068. else
  1069. Result:=Nil;
  1070. end;
  1071. procedure TMediaWidget.SetBool(AIndex: Integer; AValue: Boolean);
  1072. Var
  1073. El : TJSObject;
  1074. Att : String;
  1075. begin
  1076. El:=GetEl;
  1077. Att:=PropAttrs[aIndex];
  1078. if Assigned(el) then
  1079. El[Att]:=aValue
  1080. else
  1081. Attrs[Att]:=IntToStr(Ord(AValue));
  1082. end;
  1083. procedure TMediaWidget.SetFloat(AIndex: Integer; AValue: Double);
  1084. Var
  1085. El : TJSObject;
  1086. Att,S : String;
  1087. begin
  1088. El:=GetEl;
  1089. Att:=PropAttrs[aIndex];
  1090. if Assigned(el) then
  1091. El[Att]:=aValue
  1092. else
  1093. begin
  1094. Str(aValue,S);
  1095. Attrs[Att]:=S;
  1096. end;
  1097. end;
  1098. procedure TMediaWidget.SetString(AIndex: Integer; AValue: String);
  1099. Var
  1100. El : TJSObject;
  1101. Att : String;
  1102. begin
  1103. El:=GetEl;
  1104. Att:=PropAttrs[aIndex];
  1105. if Assigned(el) then
  1106. El[Att]:=aValue
  1107. else
  1108. Attrs[Att]:=aValue;
  1109. end;
  1110. function TMediaWidget.getEl: TJSObject;
  1111. begin
  1112. Result:=Element;
  1113. if Not Assigned(Result) then
  1114. Result:=Self.StoredAttrs;
  1115. end;
  1116. { TVideoWidget }
  1117. constructor TVideoWidget.Create(aOwner: TComponent);
  1118. begin
  1119. inherited Create(aOwner);
  1120. elementTag:=etVideo;
  1121. end;
  1122. { TAudioWidget }
  1123. constructor TAudioWidget.Create(aOwner: TComponent);
  1124. begin
  1125. inherited Create(aOwner);
  1126. elementTag:=etAudio;
  1127. end;
  1128. { TSelectWidget.TStringsSelectOptionEnumerator }
  1129. constructor TSelectWidget.TStringsSelectOptionEnumerator.Create(ASelect: TCustomSelectWidget);
  1130. begin
  1131. inherited Create(ASelect);
  1132. FCurrent:=-1;
  1133. end;
  1134. function TSelectWidget.TStringsSelectOptionEnumerator.OptionText: String;
  1135. begin
  1136. Result:=TSelectWidget(Select).Items[FCurrent];
  1137. end;
  1138. function TSelectWidget.TStringsSelectOptionEnumerator.HasValue: boolean;
  1139. begin
  1140. Result:=FCurrent<TSelectWidget(Select).Values.Count;
  1141. end;
  1142. function TSelectWidget.TStringsSelectOptionEnumerator.Value: string;
  1143. begin
  1144. Result:=TSelectWidget(Select).Values[FCurrent];
  1145. end;
  1146. function TSelectWidget.TStringsSelectOptionEnumerator.MoveNext: Boolean;
  1147. begin
  1148. Result:=FCurrent<TSelectWidget(Select).Items.Count-1;
  1149. if Result then
  1150. Inc(FCurrent);
  1151. end;
  1152. { TCustomSelectWidget.TSelectOptionEnumerator }
  1153. constructor TCustomSelectWidget.TSelectOptionEnumerator.Create(ASelect: TCustomSelectWidget);
  1154. begin
  1155. FSelect:=ASelect;
  1156. end;
  1157. function TCustomSelectWidget.TSelectOptionEnumerator.HasValue: boolean;
  1158. begin
  1159. Result:=False;
  1160. end;
  1161. function TCustomSelectWidget.TSelectOptionEnumerator.Value: string;
  1162. begin
  1163. Result:='';
  1164. end;
  1165. constructor TTableRowCountEnumerator.Create(ATable: TCustomTableWidget; aCount: Integer);
  1166. begin
  1167. Inherited Create(aTable);
  1168. FRowCount:=aCount;
  1169. end;
  1170. function TTableRowCountEnumerator.MoveNext: Boolean;
  1171. begin
  1172. Result:=Inherited MoveNext and (CurrentRow<RowCount)
  1173. end;
  1174. { TTableWidgetCellData }
  1175. procedure TTableWidgetCellData.SetRowColKind(aRow, aCol: Integer; aKind: TRowKind);
  1176. begin
  1177. if (aRow<>-1) then
  1178. FRow:=aRow;
  1179. if (aCol<>-1) then
  1180. FCol:=aCol;
  1181. FKind:=aKind;
  1182. end;
  1183. procedure TTableWidgetCellData.Reset;
  1184. begin
  1185. Ftag:='td';
  1186. FClassNames:='';
  1187. FText:='';
  1188. FContent:=Nil;
  1189. FAsHTML:=False;
  1190. FWidget:=Nil;
  1191. end;
  1192. constructor TTableWidgetCellData.Create(aTable: TCustomTableWidget; aTableID: String);
  1193. begin
  1194. FTable:=aTable;
  1195. FTableID:=aTableID;
  1196. SetRowColKind(0,0,rkBody);
  1197. end;
  1198. { TCustomTableWidget }
  1199. procedure TCustomTableWidget.SetColumns(AValue: TCustomTableColumns);
  1200. begin
  1201. if FColumns=AValue then Exit;
  1202. FColumns.Assign(AValue);
  1203. end;
  1204. procedure TCustomTableWidget.SetCaption(AValue: String);
  1205. begin
  1206. if FCaption=AValue then Exit;
  1207. FCaption:=AValue;
  1208. if isRendered then Refresh;
  1209. end;
  1210. function TCustomTableWidget.DoCellClick(aEvent: TJSMouseEvent): boolean;
  1211. begin
  1212. If Assigned(FOnCellClick) then
  1213. FOnCellClick(Self,aEvent);
  1214. If Assigned(FOnRowClick) then
  1215. FOnRowClick(Self,aEvent);
  1216. Result:=False;
  1217. // Writeln('On click for cell',aEvent.targetElement.innerText);
  1218. end;
  1219. function TCustomTableWidget.DoHeaderCellClick(aEvent: TJSMouseEvent): boolean;
  1220. begin
  1221. If Assigned(FOnHeaderCellClick) then
  1222. FOnHeaderCellClick(Self,aEvent);
  1223. If Assigned(FOnHeaderRowClick) then
  1224. FOnHeaderRowClick(Self,aEvent);
  1225. Result:=False;
  1226. // Writeln('On click for header cell',aEvent.targetElement.innerText);
  1227. end;
  1228. function TCustomTableWidget.DoFooterCellClick(aEvent: TJSMouseEvent): boolean;
  1229. begin
  1230. If Assigned(FOnFooterCellClick) then
  1231. FOnFooterCellClick(Self,aEvent);
  1232. If Assigned(FOnFooterRowClick) then
  1233. FOnFooterRowClick(Self,aEvent);
  1234. Result:=False;
  1235. // Writeln('On click for Footer cell',aEvent.targetElement.innerText);
  1236. end;
  1237. function TCustomTableWidget.DoRowClick(aEvent: TJSMouseEvent): boolean;
  1238. begin
  1239. If Assigned(FOnRowClick) then
  1240. FOnRowClick(Self,aEvent);
  1241. Result:=False;
  1242. // Writeln('On click for Row',aEvent.targetElement.innerText);
  1243. end;
  1244. function TCustomTableWidget.DoHeaderRowClick(aEvent: TJSMouseEvent): boolean;
  1245. begin
  1246. If Assigned(FOnHeaderRowClick) then
  1247. FOnHeaderRowClick(Self,aEvent);
  1248. Result:=False;
  1249. // Writeln('On click for Header Row',aEvent.targetElement.innerText);
  1250. end;
  1251. function TCustomTableWidget.DoFooterRowClick(aEvent: TJSMouseEvent): boolean;
  1252. begin
  1253. If Assigned(FOnFooterRowClick) then
  1254. FOnFooterRowClick(Self,aEvent);
  1255. Result:=False;
  1256. // Writeln('On click for Footer Row',aEvent.targetElement.innerText);
  1257. end;
  1258. procedure TCustomTableWidget.SetTableOptions(AValue: TTableOptions);
  1259. begin
  1260. if FTableOptions=AValue then Exit;
  1261. FTableOptions:=AValue;
  1262. if IsRendered then
  1263. Refresh;
  1264. end;
  1265. procedure TCustomTableWidget.AppendCaption(aCaptionElement: TJSHTMLElement);
  1266. begin
  1267. aCaptionElement.InnerHTML:=Caption;
  1268. end;
  1269. function TCustomTableWidget.GetRowEnumerator(aKind: TRowKind): TTableRowEnumerator;
  1270. begin
  1271. Case aKind of
  1272. rkHeader : Result:=TTableRowCountEnumerator.Create(Self,1);
  1273. rkFooter : Result:=TTableRowCountEnumerator.Create(Self,1);
  1274. rkBody : Result:=GetBodyRowEnumerator;
  1275. end;
  1276. end;
  1277. procedure TTableRowEnumerator.GetCellData(aCell: TTableWidgetCellData);
  1278. Var
  1279. K : TRowKind;
  1280. begin
  1281. K:=aCell.Kind;
  1282. Case K of
  1283. rkHeader:
  1284. begin
  1285. aCell.Tag:='th';
  1286. aCell.Text:=ACell.Column.Caption;
  1287. end;
  1288. rkFooter,
  1289. rkBody :
  1290. begin
  1291. aCell.Tag:='td';
  1292. end;
  1293. end;
  1294. end;
  1295. function TCustomTableWidget.HTMLTag: String;
  1296. begin
  1297. Result:='table';
  1298. end;
  1299. function TCustomTableWidget.RenderCell(aCell: TTableWidgetCellData): TJSHTMLElement;
  1300. Const
  1301. Aligns : Array[TAlignment] of string = ('left','right','center');
  1302. RowChecks : Array[TRowKind] of TTableOption = (toHeaderCellDataRow,toBodyCellDataRow,toFooterCellDataRow);
  1303. ColChecks : Array[TRowKind] of TTableOption = (toHeaderCellDataCol,toBodyCellDataCol,toFooterCellDataCol);
  1304. Var
  1305. C : TJSHtmlElement;
  1306. cl : THTMLNotifyEvent;
  1307. K : TRowKind;
  1308. M : THTMLClickEventHandler;
  1309. elID : string;
  1310. begin
  1311. K:=aCell.Kind;
  1312. if (toCellID in TableOptions) or Assigned(aCell.Widget) then
  1313. elID:=aCell.TableID+'-'+RowKindNames[K]+'-'+IntToStr(ACell.Row)+'-'+IntToStr(aCell.Col)
  1314. else
  1315. elID:='';
  1316. C:=CreateElement(aCell.Tag,elID);
  1317. if aCell.Widget<>Nil then
  1318. aCell.Widget.ParentID:=elID;
  1319. if aCell.Content<>Nil then
  1320. C.AppendChild(aCell.Content)
  1321. else if aCell.AsHTML then
  1322. C.innerHTML:=aCell.text
  1323. else
  1324. C.innerText:=aCell.text;
  1325. C.className:=AddClasses(aCell.Column.ClassNames,aCell.ClassNames);
  1326. if ACell.Column.Alignment<>taLeftJustify then
  1327. C.Style.setProperty('text-align',Aligns[ACell.Column.Alignment]);
  1328. Case K of
  1329. rkBody :
  1330. begin
  1331. CL:=FOnCellClick;
  1332. M:=@DoCellClick;
  1333. end;
  1334. rkHeader :
  1335. begin
  1336. CL:=FOnHeaderCellClick;
  1337. M:=@DoHeaderCellClick;
  1338. end;
  1339. rkFooter :
  1340. begin
  1341. CL:=FOnFooterCellClick;
  1342. M:=@DoFooterCellClick;
  1343. end;
  1344. else
  1345. CL:=Nil;
  1346. M:=nil;
  1347. end;
  1348. if Assigned(cl) or (RowChecks[K] in TableOptions) then
  1349. begin
  1350. C.dataset['row']:=ACell.Row;
  1351. C.Dataset['kind']:=RowKindNames[K];
  1352. end;
  1353. if Assigned(cl) or (ColChecks[K] in TableOptions) then
  1354. begin
  1355. C.dataset['col']:=ACell.Col;
  1356. C.Dataset['kind']:=RowKindNames[K];
  1357. end;
  1358. if Assigned(M) then
  1359. C.OnClick:=M;
  1360. if aCell.Widget<>Nil then
  1361. TJSArray(FWidgets).Push(aCell.Widget);
  1362. Result:=C;
  1363. end;
  1364. procedure TCustomTableWidget.RenderRow(aEnum: TTableRowEnumerator; aParent: TJSHTMLElement; aKind: TRowKind; aCell: TTableWidgetCellData);
  1365. Var
  1366. I: integer;
  1367. begin
  1368. For I:=0 to CustomColumns.Count-1 do
  1369. if CustomColumns[i].RenderColumn then
  1370. begin
  1371. aCell.Reset;
  1372. aCell.FColumn:=CustomColumns[i];
  1373. aCell.SetRowColKind(-1,I,aKind);
  1374. // Writeln(CellKinds[aKind],' cell before : ',aCell.Tag,' data : ',aCell.Text);
  1375. aEnum.GetCellData(aCell);
  1376. // Writeln(CellKinds[aKind],' cell after : ',aCell.Tag,' data : ',aCell.Text);
  1377. if aCell.Tag='' then
  1378. ACell.Tag:=CellTags[aKind];
  1379. if Assigned(FOnGetCellData) then
  1380. FOnGetCellData(Self,aEnum,aCell);
  1381. aParent.appendChild(RenderCell(aCell));
  1382. end;
  1383. end;
  1384. procedure TCustomTableWidget.RenderRows(aParent: TJSHTMLElement; aKind: TRowKind; aCell: TTableWidgetCellData);
  1385. Const
  1386. TableRowChecks : Array[TRowKind] of TTableOption = (toHeaderRowData,toBodyRowData,toFooterRowData);
  1387. Var
  1388. RowEl : TJSHTMLElement;
  1389. Enum : TTableRowEnumerator;
  1390. M : THTMLClickEventHandler;
  1391. cl : THTMLNotifyEvent;
  1392. elid : String;
  1393. begin
  1394. Enum:=GetRowEnumerator(aKind);
  1395. if Enum=Nil then
  1396. Exit;
  1397. try
  1398. While Enum.MoveNext do
  1399. begin
  1400. if toRowID in TableOptions then
  1401. elID:=aCell.TableID+'-'+RowKindNames[aKind]+'-'+IntToStr(Enum.CurrentRow)
  1402. else
  1403. elID:='';
  1404. RowEl:=CreateElement('tr',elID);
  1405. aCell.SetRowColKind(Enum.CurrentRow,-1,aKind);
  1406. Case aKind of
  1407. rkBody :
  1408. begin
  1409. CL:=FOnRowClick;
  1410. M:=@DoRowClick;
  1411. end;
  1412. rkHeader :
  1413. begin
  1414. CL:=FOnHeaderRowClick;
  1415. M:=@DoHeaderRowClick;
  1416. end;
  1417. rkFooter :
  1418. begin
  1419. CL:=FOnFooterRowClick;
  1420. M:=@DoFooterRowClick;
  1421. end;
  1422. end;
  1423. if Assigned(CL) or (TableRowChecks[Akind] in TableOptions) then
  1424. begin
  1425. RowEl.dataset['row']:=Enum.CurrentRow;
  1426. RowEl.dataset['kind']:=RowKindNames[aKind];
  1427. end;
  1428. if Assigned(M) then
  1429. RowEl.OnClick:=M;
  1430. RenderRow(Enum,RowEl,aKind,aCell);
  1431. aParent.AppendChild(RowEl);
  1432. end;
  1433. finally
  1434. Enum.Free;
  1435. end;
  1436. end;
  1437. procedure TCustomTableWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1438. begin
  1439. inherited ApplyWidgetSettings(aElement);
  1440. RenderData(aElement);
  1441. end;
  1442. procedure TCustomTableWidget.RenderData(aElement: TJSHTMLElement);
  1443. Var
  1444. El : TJSHTMLElement;
  1445. aCell : TTableWidgetCellData;
  1446. W : TWebWidget;
  1447. begin
  1448. FWidgets:=[];
  1449. if (Caption<>'') then
  1450. begin
  1451. El:=CreateElement('caption',aElement.ID+'-caption');
  1452. AppendCaption(EL);
  1453. aElement.AppendChild(EL);
  1454. end;
  1455. aCell:=CreateCellData(aElement.ID);
  1456. If (CustomColumns.Count=0) then
  1457. CreateDefaultColumns;
  1458. if toHeaderRow in TableOptions then
  1459. begin
  1460. if toHeader in TableOptions then
  1461. begin
  1462. El:=CreateElement('thead',aElement.ID+'-head');
  1463. aElement.AppendChild(el);
  1464. end
  1465. else
  1466. El:=aElement;
  1467. aCell.SetRowColKind(-1,-1,rkHeader);
  1468. RenderRows(El,rkHeader,aCell);
  1469. end;
  1470. if toBody in TableOptions then
  1471. begin
  1472. El:=CreateElement('tbody',aElement.ID+'-body');
  1473. aElement.AppendChild(el);
  1474. end
  1475. else
  1476. El:=aElement;
  1477. aCell.SetRowColKind(-1,-1,rkBody);
  1478. RenderRows(El,rkBody,aCell);
  1479. if toFooterRow in TableOptions then
  1480. begin
  1481. if toFooter in TableOptions then
  1482. begin
  1483. El:=CreateElement('tFoot',aElement.ID+'-foot');
  1484. aElement.AppendChild(el);
  1485. end
  1486. else
  1487. El:=aElement;
  1488. aCell.SetRowColKind(-1,-1,rkFooter);
  1489. RenderRows(El,rkFooter,aCell);
  1490. end;
  1491. for W in FWidgets do
  1492. W.Refresh;
  1493. FWidgets:=[];
  1494. end;
  1495. function TCustomTableWidget.CreateCellData(const aTableID : String): TTableWidgetCellData;
  1496. begin
  1497. Result:=TTableWidgetCellData.Create(Self,aTableID);
  1498. end;
  1499. function TCustomTableWidget.CreateColumns: TCustomTableColumns;
  1500. begin
  1501. Result:=TCustomTableColumns.Create(TCustomTableColumn);
  1502. end;
  1503. function TCustomTableWidget.DefaultTableOptions: TTableOptions;
  1504. begin
  1505. Result:=[toHeader,toBody,toFooter,toHeaderRow]
  1506. end;
  1507. procedure TCustomTableWidget.CreateDefaultColumns;
  1508. begin
  1509. // Do nothing
  1510. end;
  1511. constructor TCustomTableWidget.Create(aOwner: TComponent);
  1512. begin
  1513. inherited Create(aOwner);
  1514. FTableOptions:=DefaultTableOptions;
  1515. FColumns:=CreateColumns;
  1516. end;
  1517. destructor TCustomTableWidget.Destroy;
  1518. begin
  1519. FreeAndNil(FColumns);
  1520. inherited Destroy;
  1521. end;
  1522. procedure TCustomTableWidget.BeginUpdate;
  1523. begin
  1524. Inc(FUpDateCount);
  1525. end;
  1526. procedure TCustomTableWidget.EndUpdate;
  1527. begin
  1528. if (FUpdateCount>0) then
  1529. Dec(FUpDateCount);
  1530. if (FUpdateCount=0) and IsRendered then
  1531. Refresh;
  1532. end;
  1533. procedure TCustomTableWidget.RefreshBody;
  1534. begin
  1535. if Not Assigned(Element) then
  1536. Refresh
  1537. else
  1538. begin
  1539. Element.Innerhtml:='';
  1540. RenderData(Element);
  1541. end;
  1542. end;
  1543. { TCustomTableColumn }
  1544. procedure TCustomTableColumn.SetAlignment(AValue: TAlignment);
  1545. begin
  1546. if FAlignment=AValue then Exit;
  1547. FAlignment:=AValue;
  1548. end;
  1549. function TCustomTableColumn.GetCaption: String;
  1550. begin
  1551. Result:=FCaption;
  1552. end;
  1553. procedure TCustomTableColumn.SetCaption(AValue: String);
  1554. begin
  1555. if FCaption=AValue then Exit;
  1556. FCaption:=AValue;
  1557. end;
  1558. procedure TCustomTableColumn.SetClassNames(AValue: String);
  1559. begin
  1560. if FClassNames=AValue then Exit;
  1561. FClassNames:=AValue;
  1562. end;
  1563. function TCustomTableColumn.RenderColumn: Boolean;
  1564. begin
  1565. Result:=True;
  1566. end;
  1567. function TCustomTableColumn.GetDisplayName: string;
  1568. begin
  1569. Result:=Caption;
  1570. end;
  1571. procedure TCustomTableColumn.Assign(Source: TPersistent);
  1572. Var
  1573. C : TCustomTableColumn;
  1574. begin
  1575. if Source is TCustomTableColumn then
  1576. begin
  1577. C:=Source as TCustomTableColumn;
  1578. FCaption:=C.FCaption;
  1579. FClassNames:=C.FClassNames;
  1580. FAlignment:=C.Alignment;
  1581. end
  1582. else
  1583. inherited Assign(Source);
  1584. end;
  1585. { TCustomTableColumns }
  1586. function TCustomTableColumns.GetCustomColumn(Index : Integer): TCustomTableColumn;
  1587. begin
  1588. Result:=TCustomTableColumn(Items[Index]);
  1589. end;
  1590. procedure TCustomTableColumns.SetCustomColumn(Index : Integer; AValue: TCustomTableColumn);
  1591. begin
  1592. Items[Index]:=aValue;
  1593. end;
  1594. function TCustomTableColumns.Add(aCaption: String): TCustomTableColumn;
  1595. begin
  1596. Result:=add as TCustomTableColumn;
  1597. Result.Caption:=aCaption;
  1598. end;
  1599. { TTableRowEnumerator }
  1600. constructor TTableRowEnumerator.Create(ATable: TCustomTableWidget);
  1601. begin
  1602. FTable:=aTable;
  1603. FCurrent:=-1;
  1604. end;
  1605. function TTableRowEnumerator.MoveNext: Boolean;
  1606. begin
  1607. Inc(FCurrent);
  1608. Result:=True;
  1609. end;
  1610. { TCustomTextWidget }
  1611. procedure TCustomTextWidget.SetEnvelopeTag(AValue: TTextTag);
  1612. begin
  1613. // Writeln('Setting text tag : ',aValue);
  1614. if FEnvelopeTag=AValue then Exit;
  1615. FEnvelopeTag:=AValue;
  1616. if (FEnvelopeTag=ttCustom) and (FCustomTag='') then
  1617. FCustomTag:='div';
  1618. if IsRendered then
  1619. Refresh;
  1620. end;
  1621. procedure TCustomTextWidget.SetCustomTag(AValue: String);
  1622. begin
  1623. if FCustomTag=AValue then Exit;
  1624. FCustomTag:=AValue;
  1625. if (FCustomTag<>'') then
  1626. FEnvelopeTag:=ttCustom;
  1627. if IsRendered then
  1628. Refresh;
  1629. end;
  1630. procedure TCustomTextWidget.SetTextMode(AValue: TTextMode);
  1631. begin
  1632. if FTextMode=AValue then Exit;
  1633. FTextMode:=AValue;
  1634. if IsRendered then
  1635. ApplyText(Element);
  1636. end;
  1637. procedure TCustomTextWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1638. begin
  1639. // Writeln('ApplyWidgetSettings: ',aElement.tagName);
  1640. inherited ApplyWidgetSettings(aElement);
  1641. ApplyText(aElement);
  1642. end;
  1643. procedure TCustomTextWidget.ApplyText(aElement: TJSHTMLElement);
  1644. begin
  1645. if FTextMode=tmText then
  1646. aElement.innerText:=GetText
  1647. else
  1648. aElement.innerHTML:=GetText;
  1649. end;
  1650. function TCustomTextWidget.HTMLTag: String;
  1651. begin
  1652. Result:=TextTagNames[FEnvelopeTag];
  1653. if Result='' then
  1654. Result:='div';
  1655. // Writeln('Getting element tag: ',Result);
  1656. end;
  1657. { TTextLinesWidget }
  1658. procedure TTextLinesWidget.SetLines(AValue: TStrings);
  1659. begin
  1660. if FLines=AValue then Exit;
  1661. FLines.Assign(AValue);
  1662. end;
  1663. procedure TTextLinesWidget.SetForceLineBreaks(AValue: Boolean);
  1664. begin
  1665. if FForceLineBreaks=AValue then Exit;
  1666. FForceLineBreaks:=AValue;
  1667. if IsRendered then
  1668. ApplyText(Element);
  1669. end;
  1670. procedure TTextLinesWidget.DoLinesChanged(Sender: TObject);
  1671. begin
  1672. if IsRendered then
  1673. ApplyText(Element);
  1674. end;
  1675. function TTextLinesWidget.GetText: String;
  1676. Var
  1677. I : integer;
  1678. begin
  1679. if (FTextMode=tmHTML) and ForceLineBreaks then
  1680. begin
  1681. Result:='';
  1682. For I:=0 to FLines.Count-1 do
  1683. Result:=Result+flines[i]+'<br/>';
  1684. end
  1685. else
  1686. Result:=FLines.Text;
  1687. end;
  1688. procedure TTextLinesWidget.ApplyText(aElement: TJSHTMLElement);
  1689. Var
  1690. I : integer;
  1691. begin
  1692. if (TextMode=tmHTML) or (Not ForceLineBreaks) then
  1693. inherited ApplyText(aElement)
  1694. else
  1695. begin
  1696. For I:=0 to FLines.Count-1 do
  1697. begin
  1698. aElement.AppendChild(Document.createTextNode(FLines[i]));
  1699. aElement.AppendChild(CreateElement('br',''));
  1700. end;
  1701. end;
  1702. end;
  1703. constructor TTextLinesWidget.Create(aOwner: TComponent);
  1704. begin
  1705. inherited Create(aOwner);
  1706. FLines:=TstringList.Create;
  1707. TstringList(FLines).OnChange:=@DoLinesChanged;
  1708. end;
  1709. destructor TTextLinesWidget.Destroy;
  1710. begin
  1711. FLines:=TstringList.Create;
  1712. inherited Destroy;
  1713. end;
  1714. { TTextWidget }
  1715. procedure TTextWidget.SetText(AValue: String);
  1716. begin
  1717. if FText=AValue then Exit;
  1718. FText:=AValue;
  1719. if IsRendered then
  1720. ApplyText(Element);
  1721. end;
  1722. function TTextWidget.GetText: String;
  1723. begin
  1724. Result:=FText;
  1725. end;
  1726. { TLabelWidget }
  1727. procedure TLabelWidget.ApplyLabelFor(aLabelElement : TJSHTMLLabelElement);
  1728. begin
  1729. if Assigned(FlabelFor) then
  1730. begin
  1731. FlabelFor.EnsureElement;
  1732. aLabelElement.for_:=FlabelFor.ElementID;
  1733. end
  1734. else
  1735. aLabelElement.for_:='';
  1736. end;
  1737. procedure TLabelWidget.SetLabelFor(AValue: TWebWidget);
  1738. begin
  1739. if (FLabelFor=AValue) then Exit;
  1740. if Assigned(FLabelFor) then
  1741. FLabelFor.RemoveFreeNotification(Self);
  1742. FLabelFor:=AValue;
  1743. if Assigned(FLabelFor) then
  1744. FLabelFor.FreeNotification(Self);
  1745. If IsRendered then
  1746. ApplyLabelFor(LabelElement);
  1747. end;
  1748. function TLabelWidget.GetText: String;
  1749. begin
  1750. if IsElementDirty then
  1751. FText:=Element.InnerText;
  1752. Result:=FText;
  1753. end;
  1754. function TLabelWidget.GetLabelEl: TJSHTMLLabelElement;
  1755. begin
  1756. Result:=TJSHTMLLabelElement(Element);
  1757. end;
  1758. procedure TLabelWidget.SetText(AValue: String);
  1759. begin
  1760. If Text=aValue then exit;
  1761. Ftext:=aValue;
  1762. If IsRendered then
  1763. Element.innerText:=aValue;
  1764. end;
  1765. procedure TLabelWidget.Notification(AComponent: TComponent; Operation: TOperation);
  1766. begin
  1767. inherited Notification(AComponent, Operation);
  1768. if (Operation=opRemove) and (aComponent=FLabelFor) then
  1769. FLabelFor:=Nil;
  1770. end;
  1771. procedure TLabelWidget.SetName(const NewName: TComponentName);
  1772. Var
  1773. Old : String;
  1774. begin
  1775. Old:=Name;
  1776. inherited SetName(NewName);
  1777. if (csDesigning in ComponentState) then
  1778. if Old=Text then
  1779. Text:=Old;
  1780. end;
  1781. procedure TLabelWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1782. var
  1783. lbl : TJSHTMLLabelElement absolute aElement;
  1784. begin
  1785. inherited ApplyWidgetSettings(aElement);
  1786. lbl.InnerText:=Text;
  1787. ApplyLabelFor(Lbl);
  1788. end;
  1789. function TLabelWidget.HTMLTag: String;
  1790. begin
  1791. Result:='label';
  1792. end;
  1793. { TSelectWidget }
  1794. function TCustomSelectWidget.GetSelectedIndex: Integer;
  1795. begin
  1796. if IsRendered then
  1797. FSelectedIndex:=SelectElement.selectedIndex;
  1798. Result:=FSelectedIndex
  1799. end;
  1800. function TCustomSelectWidget.GetMultiple: Boolean;
  1801. begin
  1802. if IsElementDirty then
  1803. FMultiple:=SelectElement.multiple;
  1804. Result:=FMultiple;
  1805. end;
  1806. function TCustomSelectWidget.GetItemCount: Integer;
  1807. begin
  1808. Result:=Length(Options);
  1809. end;
  1810. function TCustomSelectWidget.GetSelected(Index : Integer): Boolean;
  1811. begin
  1812. if (Index<0) or (Index>=Length(Foptions)) then
  1813. Raise EWidgets.CreateFmt(SErrInvalidIndex,[Index,Length(Foptions)-1]);
  1814. Result:=FOptions[Index].Selected
  1815. end;
  1816. function TCustomSelectWidget.GetSelect: TJSHTMLSelectElement;
  1817. begin
  1818. Result:=TJSHTMLSelectElement(Element);
  1819. end;
  1820. function TCustomSelectWidget.GetSelectionCount: Integer;
  1821. begin
  1822. Result:=SelectElement.selectedOptions.length;
  1823. end;
  1824. function TCustomSelectWidget.GetSelectionItem(aIndex : Integer): String;
  1825. begin
  1826. if (aIndex<0) or (aindex>=GetSelectionCount) then
  1827. Raise EWidgets.CreateFmt(SErrInvalidIndex,[aIndex,GetSelectionCount-1]);
  1828. Result:=TJSHTMLOptionElement(SelectElement.selectedOptions.item(aIndex)).innerText;
  1829. end;
  1830. function TCustomSelectWidget.GetSelectionValue(aIndex : Integer): String;
  1831. begin
  1832. if (aIndex<0) or (aindex>=GetSelectionCount) then
  1833. Raise EWidgets.CreateFmt(SErrInvalidIndex,[aIndex,GetSelectionCount-1]);
  1834. Result:=TJSHTMLOptionElement(SelectElement.selectedOptions.item(aIndex)).value;
  1835. end;
  1836. function TCustomSelectWidget.GetSize: Integer;
  1837. begin
  1838. if IsElementDirty then
  1839. FSize:=SelectElement.Size;
  1840. Result:=FSize;
  1841. end;
  1842. procedure TCustomSelectWidget.SetMultiple(AValue: Boolean);
  1843. begin
  1844. If (AValue=Multiple) then exit;
  1845. FMultiple:=aValue;
  1846. If IsRendered then
  1847. SelectElement.multiple:=FMultiple;
  1848. end;
  1849. procedure TCustomSelectWidget.SetSelected(Index : Integer; AValue: Boolean);
  1850. begin
  1851. if (Index<0) or (Index>=Length(Foptions)) then
  1852. Raise EWidgets.CreateFmt(SErrInvalidIndex,[Index,Length(Foptions)-1]);
  1853. FOptions[Index].Selected:=aValue;
  1854. end;
  1855. procedure TCustomSelectWidget.SetSelectedIndex(AValue: Integer);
  1856. begin
  1857. if (SelectedIndex=aValue) then
  1858. Exit;
  1859. FSelectedIndex:=aValue;
  1860. if IsRendered then
  1861. SelectElement.SelectedIndex:=FSelectedIndex;
  1862. if Assigned(OnChange) then
  1863. OnChange(Self,Nil);
  1864. end;
  1865. procedure TCustomSelectWidget.SetSize(AValue: Integer);
  1866. begin
  1867. If (AValue=Size) then exit;
  1868. FSize:=aValue;
  1869. If IsRendered then
  1870. SelectElement.Size:=FSize;
  1871. end;
  1872. procedure TCustomSelectWidget.BuildOptions(aSelect: TJSHTMLSelectElement);
  1873. Var
  1874. O : TJSHTMLOptionElement;
  1875. Idx : Integer;
  1876. enum : TSelectOptionEnumerator;
  1877. begin
  1878. // Clear
  1879. SetLength(FOptions,0);
  1880. aSelect.InnerHTML:='';
  1881. // Rebuild
  1882. Idx:=0;
  1883. enum:=CreateOptionEnumerator;
  1884. While enum.MoveNext do
  1885. begin
  1886. O:=TJSHTMLOptionElement(CreateElement('option',''));
  1887. O.innerText:=enum.OptionText;
  1888. if enum.HasValue then
  1889. O.value:=enum.Value;
  1890. if Idx=FSelectedIndex then
  1891. O.selected:=True;
  1892. aSelect.AppendChild(O);
  1893. Inc(Idx);
  1894. end;
  1895. SetLength(Foptions,Idx);
  1896. Dec(idx);
  1897. While Idx>=0 do
  1898. begin
  1899. FOptions[Idx]:=TJSHTMLOptionElement(aSelect.Children[Idx]);
  1900. dec(Idx);
  1901. end;
  1902. end;
  1903. constructor TCustomSelectWidget.Create(aOWner: TComponent);
  1904. begin
  1905. inherited Create(aOWner);
  1906. FSelectedIndex:=-1;
  1907. end;
  1908. procedure TCustomSelectWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1909. Var
  1910. el : TJSHTmlSelectElement absolute aElement;
  1911. begin
  1912. inherited ApplyWidgetSettings(aElement);
  1913. el.multiple:=Self.Multiple;
  1914. el.Size:=Self.Size;
  1915. BuildOptions(el);
  1916. // We need to force this.
  1917. if SelectedIndex=-1 then
  1918. el.selectedIndex:=-1;
  1919. end;
  1920. function TCustomSelectWidget.HTMLTag: String;
  1921. begin
  1922. Result:='select';
  1923. end;
  1924. { TSelectWidget }
  1925. function TSelectWidget.GetItems: TStrings;
  1926. begin
  1927. Result:=FItems;
  1928. end;
  1929. function TSelectWidget.GetValues: TStrings;
  1930. begin
  1931. Result:=FValues;
  1932. end;
  1933. procedure TSelectWidget.OptionsChanged(Sender: TObject);
  1934. begin
  1935. if IsRendered then
  1936. BuildOptions(SelectElement);
  1937. end;
  1938. procedure TSelectWidget.setItems(AValue: TStrings);
  1939. begin
  1940. If (AValue=FItems) then exit;
  1941. FItems.Assign(aValue);
  1942. end;
  1943. procedure TSelectWidget.setValues(AValue: TStrings);
  1944. begin
  1945. If (AValue=FValues) then exit;
  1946. FValues.Assign(aValue);
  1947. end;
  1948. function TSelectWidget.CreateOptionEnumerator: TSelectOptionEnumerator;
  1949. begin
  1950. Result:=TStringsSelectOptionEnumerator.Create(Self);
  1951. end;
  1952. constructor TSelectWidget.Create(aOWner: TComponent);
  1953. begin
  1954. inherited Create(aOWner);
  1955. FItems:=TStringList.Create;
  1956. TStringList(FItems).OnChange:=@OptionsChanged;
  1957. FValues:=TStringList.Create;
  1958. TStringList(FValues).OnChange:=@OptionsChanged;
  1959. end;
  1960. destructor TSelectWidget.Destroy;
  1961. begin
  1962. FreeAndNil(FItems);
  1963. FreeAndNil(FValues);
  1964. inherited Destroy;
  1965. end;
  1966. { TImageWidget }
  1967. function TImageWidget.GetHeight: Integer;
  1968. begin
  1969. if IsElementDirty then
  1970. FHeight:=ImgElement.Height;
  1971. Result:=Fheight;
  1972. end;
  1973. function TImageWidget.GetImg: TJSHTMLImageElement;
  1974. begin
  1975. Result:=TJSHTMLImageElement(Element);
  1976. end;
  1977. function TImageWidget.GetSrc: String;
  1978. begin
  1979. if IsElementDirty then
  1980. FSrc:=ImgElement.Src;
  1981. Result:=FSrc;
  1982. end;
  1983. function TImageWidget.GetWidth: Integer;
  1984. begin
  1985. if IsElementDirty then
  1986. FWidth:=ImgElement.Width;
  1987. Result:=FWidth;
  1988. end;
  1989. procedure TImageWidget.SetHeight(AValue: Integer);
  1990. begin
  1991. if AValue=Height then exit;
  1992. FHeight:=AValue;
  1993. If isrendered then
  1994. ImgElement.Height:=aValue;
  1995. end;
  1996. procedure TImageWidget.SetSrc(AValue: String);
  1997. begin
  1998. if AValue=Src then exit;
  1999. FSrc:=AValue;
  2000. If isrendered then
  2001. ImgElement.Src:=FSrc;
  2002. end;
  2003. procedure TImageWidget.SetWidth(AValue: Integer);
  2004. begin
  2005. if AValue=Width then exit;
  2006. FWidth:=AValue;
  2007. If isrendered then
  2008. ImgElement.Width:=aValue;
  2009. end;
  2010. procedure TImageWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2011. var
  2012. img : TJSHTMLImageElement absolute aElement;
  2013. begin
  2014. inherited ApplyWidgetSettings(aElement);
  2015. Img.Src:=FSrc;
  2016. Img.Height:=FHeight;
  2017. Img.Width:=FWidth;
  2018. end;
  2019. function TImageWidget.HTMLTag: String;
  2020. begin
  2021. Result:='img';
  2022. end;
  2023. { TTextAreaWidget }
  2024. procedure TTextAreaWidget.SetLines(AValue: TStrings);
  2025. begin
  2026. if FLines=AValue then Exit;
  2027. FLines.Assign(AValue);
  2028. end;
  2029. procedure TTextAreaWidget.SetMaxLength(AValue: Cardinal);
  2030. begin
  2031. if FMaxLength=AValue then Exit;
  2032. FMaxLength:=AValue;
  2033. if IsRendered then
  2034. TextArea.maxLength:=aValue;
  2035. end;
  2036. procedure TTextAreaWidget.SetReadonly(AValue: Boolean);
  2037. begin
  2038. If aValue=ReadOnly then exit;
  2039. FReadOnly:=aValue;
  2040. if IsRendered then
  2041. TextArea.Readonly:=FReadOnly;
  2042. end;
  2043. procedure TTextAreaWidget.SetRequired(AValue: Boolean);
  2044. begin
  2045. If aValue=Required then exit;
  2046. FRequired:=aValue;
  2047. if IsRendered then
  2048. TextArea.Required:=FRequired;
  2049. end;
  2050. function TTextAreaWidget.GetColumns: Cardinal;
  2051. begin
  2052. if IsElementDirty then
  2053. FColumns:=TextArea.Cols;
  2054. Result:=FColumns;
  2055. end;
  2056. procedure TTextAreaWidget.DoLineChanges(Sender: TObject);
  2057. begin
  2058. if isRendered and not FIgnoreChanges then
  2059. ApplyLines(TextArea);
  2060. end;
  2061. function TTextAreaWidget.GetLines: TStrings;
  2062. begin
  2063. // We may want to change this to something more efficient. Maybe handle onchange
  2064. // Note that if yo
  2065. if IsElementDirty then
  2066. begin
  2067. FIgnoreChanges:=True;
  2068. try
  2069. LinesFromHTML(Element.InnerHTml);
  2070. finally
  2071. FIgnoreChanges:=False;
  2072. end;
  2073. end;
  2074. Result:=FLines;
  2075. end;
  2076. function TTextAreaWidget.GetReadOnly: Boolean;
  2077. begin
  2078. if IsElementDirty then
  2079. FReadonly:=TextArea.readOnly;
  2080. Result:=FReadonly;
  2081. end;
  2082. function TTextAreaWidget.GetRequired: Boolean;
  2083. begin
  2084. if IsElementDirty then
  2085. FRequired:=TextArea.Required;
  2086. Result:=FRequired;
  2087. end;
  2088. function TTextAreaWidget.GetRows: Cardinal;
  2089. begin
  2090. if IsElementDirty then
  2091. FRows:=TextArea.Rows;
  2092. Result:=FRows;
  2093. end;
  2094. function TTextAreaWidget.GetText: String;
  2095. begin
  2096. if IsElementDirty then
  2097. Result:=Element.InnerHTML
  2098. else
  2099. Result:=FLines.Text;
  2100. end;
  2101. function TTextAreaWidget.GetValueName: string;
  2102. begin
  2103. if IsElementDirty then
  2104. FValueName:=Element.Name;
  2105. Result:=FValueName;
  2106. end;
  2107. procedure TTextAreaWidget.SetColumns(AValue: Cardinal);
  2108. begin
  2109. if AValue=FColumns then exit;
  2110. FColumns:=aValue;
  2111. if isRendered then
  2112. TextArea.cols:=aValue;
  2113. end;
  2114. procedure TTextAreaWidget.SetRows(AValue: Cardinal);
  2115. begin
  2116. if AValue=FRows then exit;
  2117. FRows:=aValue;
  2118. if isRendered then
  2119. TextArea.Rows:=aValue;
  2120. end;
  2121. procedure TTextAreaWidget.SetText(AValue: String);
  2122. begin
  2123. if isRendered then
  2124. element.InnerText:=aValue
  2125. else
  2126. LinesFromHTML(aValue);
  2127. end;
  2128. procedure TTextAreaWidget.SetValueName(AValue: string);
  2129. begin
  2130. if aValue=FValueName then exit;
  2131. FValueName:=aValue;
  2132. if IsRendered then
  2133. TextArea.Name:=aValue;
  2134. end;
  2135. procedure TTextAreaWidget.SetName(const NewName: TComponentName);
  2136. var
  2137. Old : String;
  2138. begin
  2139. Old:=Name;
  2140. inherited SetName(NewName);
  2141. if csDesigning in ComponentState then
  2142. begin
  2143. if (FLines.Count=0) then
  2144. FLines.Add(Name)
  2145. else if (FLines.Count=1) and (FLines[0]=Old) then
  2146. FLines[0]:=Name;
  2147. end;
  2148. end;
  2149. procedure TTextAreaWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2150. var
  2151. area : TJSHTMLTextAreaElement absolute aElement;
  2152. begin
  2153. inherited ApplyWidgetSettings(aElement);
  2154. if FMaxLength>0 then
  2155. area.maxlength:=FMaxLength;
  2156. if FColumns>0 then
  2157. area.cols:=FColumns;
  2158. if FRows>0 then
  2159. area.Rows:=FRows;
  2160. if FLines.Count>0 then
  2161. ApplyLines(area);
  2162. if FValueName<>'' then
  2163. area.Name:=FValueName;
  2164. area.Readonly:=FReadOnly;
  2165. area.Required:=FRequired;
  2166. ApplyWrap(area);
  2167. end;
  2168. constructor TTextAreaWidget.Create(aOwner: TComponent);
  2169. begin
  2170. inherited Create(aOwner);
  2171. FLines:=TStringList.Create;
  2172. TStringList(FLines).OnChange:=@DoLineChanges;
  2173. FColumns:=50;
  2174. FRows:=10;
  2175. end;
  2176. destructor TTextAreaWidget.Destroy;
  2177. begin
  2178. FreeAndNil(Flines);
  2179. inherited;
  2180. end;
  2181. class function TTextAreaWidget.AllowChildren: Boolean;
  2182. begin
  2183. Result:=False;
  2184. end;
  2185. function TTextAreaWidget.GetTextArea: TJSHTMLTextAreaElement;
  2186. begin
  2187. Result:=TJSHTMLTextAreaElement(Element);
  2188. end;
  2189. procedure TTextAreaWidget.ApplyWrap(aElement :TJSHTMLTextAreaElement);
  2190. Const
  2191. Wraps : Array[TTextAreaWrap] of string = ('soft','hard','off');
  2192. begin
  2193. aElement.wrap:=Wraps[FWrap];
  2194. end;
  2195. procedure TTextAreaWidget.ApplyLines(aElement: TJSHTMLTextAreaElement);
  2196. begin
  2197. aElement.innerHTML:=FLines.Text;
  2198. end;
  2199. procedure TTextAreaWidget.LinesFromHTML(aHTML: String);
  2200. begin
  2201. FLines.Text:= StringReplace(aHTML,'<br>',sLineBreak,[rfIgnoreCase,rfReplaceAll]);
  2202. end;
  2203. procedure TTextAreaWidget.SetWrap(AValue: TTextAreaWrap);
  2204. begin
  2205. if FWrap=AValue then Exit;
  2206. FWrap:=AValue;
  2207. if IsRendered then
  2208. ApplyWrap(TextArea)
  2209. end;
  2210. function TTextAreaWidget.HTMLTag: String;
  2211. begin
  2212. result:='textarea';
  2213. end;
  2214. { TCheckboxInputWidget }
  2215. function TCheckboxInputWidget.InputType: String;
  2216. begin
  2217. Result:='checkbox';
  2218. end;
  2219. { TRadioInputWidget }
  2220. function TRadioInputWidget.InputType: String;
  2221. begin
  2222. Result:='radio';
  2223. end;
  2224. { THiddenInputWidget }
  2225. class function THiddenInputWidget.AllowChildren: Boolean;
  2226. begin
  2227. Result:=False;
  2228. end;
  2229. function THiddenInputWidget.InputType: String;
  2230. begin
  2231. Result:='hidden';
  2232. end;
  2233. { TFileInputWidget }
  2234. procedure TFileInputWidget.SetMultiple(AValue: Boolean);
  2235. begin
  2236. if FMultiple=AValue then Exit;
  2237. FMultiple:=AValue;
  2238. if Isrendered then
  2239. InputElement.multiple:=FMultiple;
  2240. end;
  2241. function TFileInputWidget.GetMultiple: Boolean;
  2242. begin
  2243. if IsElementDirty then
  2244. FMultiple:=InputElement.multiple;
  2245. Result:=FMultiple;
  2246. end;
  2247. function TFileInputWidget.GetFileName(aIndex : Integer): String;
  2248. begin
  2249. Result:=InputElement.files.Files[aIndex].name;
  2250. end;
  2251. function TFileInputWidget.GetFileSize(aIndex : Integer): NativeInt;
  2252. begin
  2253. Result:=InputElement.files.Files[aIndex].Size;
  2254. end;
  2255. function TFileInputWidget.GetFileType(aIndex : Integer): String;
  2256. begin
  2257. Result:=InputElement.files.Files[aIndex]._Type;
  2258. end;
  2259. function TFileInputWidget.GetFileCount: Integer;
  2260. begin
  2261. Result:=InputElement.files.Length;
  2262. end;
  2263. function TFileInputWidget.GetFileDate(aIndex : Integer): TDateTime;
  2264. begin
  2265. Result:=JSDateToDateTime(InputElement.files.Files[aIndex].lastModifiedDate);
  2266. end;
  2267. function TFileInputWidget.GetFileInfo(aIndex : Integer): TFileInfo;
  2268. Var
  2269. f : TJSHTMLFile;
  2270. begin
  2271. F:=InputElement.files.Files[aIndex];
  2272. Result.Name:=F.name;
  2273. Result.Size:=F.size;
  2274. Result.FileType:=F._type;
  2275. Result.TimeStamp:= JSDateToDateTime(F.lastModifiedDate);
  2276. end;
  2277. procedure TFileInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2278. Var
  2279. Old : String;
  2280. begin
  2281. Old:=FValue;
  2282. FValue:='';
  2283. try
  2284. inherited ApplyWidgetSettings(aElement);
  2285. TJSHTMLInputElement(aElement).multiple:=FMultiple;
  2286. finally
  2287. FValue:=Old;
  2288. end;
  2289. end;
  2290. class function TFileInputWidget.AllowChildren: Boolean;
  2291. begin
  2292. Result:=False;
  2293. end;
  2294. function TFileInputWidget.InputType: String;
  2295. begin
  2296. Result:='file';
  2297. end;
  2298. { TDateInputWidget }
  2299. function TDateInputWidget.GetDate: TDateTime;
  2300. var
  2301. aDate : TDateTime;
  2302. begin
  2303. if IsElementDirty then
  2304. begin
  2305. aDate:=ScanDateTime('yyyy-mm-dd',Value);
  2306. if aDate<>0 then
  2307. FDate:=aDate;
  2308. end;
  2309. Result:=FDate;
  2310. end;
  2311. procedure TDateInputWidget.SetDate(AValue: TDateTime);
  2312. begin
  2313. FDate:=aValue;
  2314. Value:=FormatDateTime('yyyy-mm-dd',FDate);
  2315. end;
  2316. function TDateInputWidget.InputType: String;
  2317. begin
  2318. Result:='date';
  2319. end;
  2320. class function TDateInputWidget.AllowChildren: Boolean;
  2321. begin
  2322. Result:=False;
  2323. end;
  2324. { TCheckableInputWidget }
  2325. procedure TCheckableInputWidget.SetChecked(AValue: Boolean);
  2326. begin
  2327. // Get actual value
  2328. if Checked=AValue then Exit;
  2329. if isRendered then
  2330. InputElement.checked:=aValue;
  2331. FChecked:=AValue;
  2332. end;
  2333. procedure TCheckableInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2334. begin
  2335. inherited ApplyWidgetSettings(aElement);
  2336. TJSHTMLInputElement(aElement).Checked:=FChecked;
  2337. end;
  2338. function TCheckableInputWidget.GetChecked: Boolean;
  2339. begin
  2340. if IsElementDirty then
  2341. FChecked:=InputElement.Checked;
  2342. Result:=FChecked;
  2343. end;
  2344. { TButtonInputWidget }
  2345. procedure TButtonInputWidget.SetButtonType(AValue: TInputButtonType);
  2346. begin
  2347. if FButtonType=AValue then Exit;
  2348. FButtonType:=AValue;
  2349. if IsRendered then
  2350. Refresh;
  2351. end;
  2352. procedure TButtonInputWidget.SetSrc(AValue: String);
  2353. begin
  2354. if FSrc=AValue then Exit;
  2355. FSrc:=AValue;
  2356. if IsRendered and (ButtonType=ibtImage) then
  2357. Element.setAttribute('src',FSrc);
  2358. end;
  2359. procedure TButtonInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2360. begin
  2361. inherited ApplyWidgetSettings(aElement);
  2362. if ButtonType=ibtImage then
  2363. aElement.setAttribute('src',FSrc);
  2364. end;
  2365. function TButtonInputWidget.InputType: String;
  2366. Const
  2367. Types : Array[TInputButtonType] of string = ('submit','reset','image');
  2368. begin
  2369. Result:=Types[FButtonType]
  2370. end;
  2371. class function TButtonInputWidget.AllowChildren: Boolean;
  2372. begin
  2373. Result:=False;
  2374. end;
  2375. { TTextInputWidget }
  2376. function TTextInputWidget.GetAsNumber: NativeInt;
  2377. begin
  2378. Result:=StrToIntDef(Value,0);
  2379. end;
  2380. function TTextInputWidget.GetMaxLength: NativeInt;
  2381. begin
  2382. if IsElementDirty then
  2383. FMaxLength:=InputElement.maxLength;
  2384. Result:=FMaxLength;
  2385. end;
  2386. function TTextInputWidget.GetMinLength: NativeInt;
  2387. begin
  2388. if IsElementDirty then
  2389. FMinLength:=InputElement.minLength;
  2390. Result:=FMinLength;
  2391. end;
  2392. function TTextInputWidget.GetTextType: TInputTextType;
  2393. begin
  2394. Result:=FTextType;
  2395. end;
  2396. procedure TTextInputWidget.SetAsNumber(AValue: NativeInt);
  2397. begin
  2398. Value:=IntToStr(aValue);
  2399. end;
  2400. procedure TTextInputWidget.SetMaxLength(AValue: NativeInt);
  2401. begin
  2402. if (aValue=FMaxLength) then exit;
  2403. FMaxLength:=aValue;
  2404. if IsRendered then
  2405. InputElement.maxLength:=FMaxLength;
  2406. end;
  2407. procedure TTextInputWidget.SetMinLength(AValue: NativeInt);
  2408. begin
  2409. if (aValue=FMinLength) then exit;
  2410. FMinLength:=aValue;
  2411. if IsRendered then
  2412. InputElement.minLength:=FMinLength;
  2413. end;
  2414. procedure TTextInputWidget.SetTextType(AValue: TInputTextType);
  2415. begin
  2416. if aValue=FTextType then exit;
  2417. FTextType:=aValue;
  2418. if IsRendered then
  2419. Refresh;
  2420. end;
  2421. procedure TTextInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2422. var
  2423. inp : TJSHTMLInputElement absolute aElement;
  2424. begin
  2425. inherited ApplyWidgetSettings(aElement);
  2426. if FMaxLength<>0 then
  2427. inp.maxLength:=FMaxLength;
  2428. if FMinLength<>0 then
  2429. inp.minLength:=FMinLength;
  2430. end;
  2431. class function TTextInputWidget.AllowChildren: Boolean;
  2432. begin
  2433. Result:=False;
  2434. end;
  2435. function TTextInputWidget.InputType: String;
  2436. Const
  2437. Types : Array[TInputTextType] of string =
  2438. ('text','password','number','email','search','tel','url','color');
  2439. begin
  2440. Result:=Types[FTextType];
  2441. end;
  2442. { TWebPage }
  2443. constructor TWebPage.Create(AOwner: TComponent);
  2444. begin
  2445. inherited Create(AOwner);
  2446. Classes:='WebPage';
  2447. end;
  2448. class function TWebPage.DefaultParentElement: TJSHTMLElement;
  2449. begin
  2450. Result:=TViewport.Instance.Element;
  2451. end;
  2452. class function TWebPage.DefaultParent: TCustomWebWidget;
  2453. begin
  2454. Result:=TViewport.Instance;
  2455. end;
  2456. procedure TWebPage.DoUnRender(aParent: TJSHTMLElement);
  2457. begin
  2458. inherited DoUnRender(aParent);
  2459. end;
  2460. function TWebPage.HTMLTag: String;
  2461. begin
  2462. Result:='div';
  2463. end;
  2464. { TViewPort }
  2465. function TViewPort.HTMLTag: String;
  2466. begin
  2467. Result:='body';
  2468. end;
  2469. class function TViewPort.FixedParent: TJSHTMLElement;
  2470. begin
  2471. Result:=TJSHTMLElement(Document.documentElement);
  2472. end;
  2473. class function TViewPort.FixedElement: TJSHTMLElement;
  2474. begin
  2475. Result:=TJSHTMLElement(Document.Body);
  2476. end;
  2477. function TViewPort.DoRenderHTML(aParent, aElement: TJSHTMLElement): TJSHTMLElement;
  2478. begin
  2479. Result:=FixedElement;
  2480. end;
  2481. constructor TViewPort.Create(aOwner: TComponent);
  2482. begin
  2483. inherited Create(aOwner);
  2484. EnsureElement;
  2485. end;
  2486. class function TViewPort.Instance: TViewPort;
  2487. begin
  2488. if Finstance=Nil then
  2489. FInstance:=TViewPort.Create(Nil);
  2490. Result:=FInstance;
  2491. end;
  2492. { TButtonWidget }
  2493. { TButtonWidget }
  2494. procedure TButtonWidget.SetText(AValue: String);
  2495. begin
  2496. if FText=AValue then Exit;
  2497. FText:=AValue;
  2498. if IsRendered then
  2499. ApplyText(Element);
  2500. end;
  2501. procedure TButtonWidget.SetTextMode(AValue: TTextMode);
  2502. begin
  2503. if FTextMode=AValue then Exit;
  2504. FTextMode:=AValue;
  2505. if IsRendered then
  2506. ApplyText(Element)
  2507. end;
  2508. procedure TButtonWidget.SetName(const NewName: TComponentName);
  2509. Var
  2510. Old : String;
  2511. begin
  2512. Old:=Name;
  2513. inherited SetName(NewName);
  2514. if (FText=Old) and (csDesigning in ComponentState) then
  2515. FText:=NewName;
  2516. end;
  2517. function TButtonWidget.HTMLTag: String;
  2518. begin
  2519. Result:='button';
  2520. end;
  2521. procedure TButtonWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2522. begin
  2523. Inherited;
  2524. ApplyText(aElement);
  2525. end;
  2526. Procedure TButtonWidget.ApplyText(aElement : TJSHTMLElement);
  2527. begin
  2528. if FTextMode=tmText then
  2529. aElement.InnerText:=FText
  2530. else
  2531. aElement.InnerHTML:=FText;
  2532. end;
  2533. procedure TButtonWidget.Click;
  2534. begin
  2535. DispatchEvent('click');
  2536. end;
  2537. { TCustomInputWidget }
  2538. function TCustomInputWidget.GetValue: String;
  2539. Var
  2540. Inp : TJSHTMLInputElement;
  2541. begin
  2542. Inp:=InputElement;
  2543. If Assigned(Inp) then
  2544. Result:=Inp.value
  2545. else
  2546. Result:=FValue
  2547. end;
  2548. function TCustomInputWidget.GetText: String;
  2549. Var
  2550. Inp : TJSHTMLElement;
  2551. begin
  2552. Inp:=Element;
  2553. If Assigned(Inp) then
  2554. Result:=Inp.InnerText
  2555. else
  2556. Result:=FText;
  2557. // Writeln('Getting text: ',Result,' inner : ',FText);
  2558. end;
  2559. function TCustomInputWidget.GetReadOnly: Boolean;
  2560. begin
  2561. if IsElementDirty then
  2562. FReadonly:=InputElement.readOnly;
  2563. Result:=FReadonly;
  2564. end;
  2565. function TCustomInputWidget.GetRequired: Boolean;
  2566. begin
  2567. if IsElementDirty then
  2568. FRequired:=InputElement.Required;
  2569. Result:=FRequired;
  2570. end;
  2571. function TCustomInputWidget.GetValueName: String;
  2572. Var
  2573. Inp : TJSHTMLInputElement;
  2574. begin
  2575. Inp:=InputElement;
  2576. If Assigned(Inp) then
  2577. Result:=Inp.Name
  2578. else
  2579. begin
  2580. Result:=FValueName;
  2581. if Result='' then
  2582. Result:=Name;
  2583. end;
  2584. end;
  2585. procedure TCustomInputWidget.SetReadonly(AValue: Boolean);
  2586. begin
  2587. If aValue=ReadOnly then exit;
  2588. FReadOnly:=aValue;
  2589. if IsRendered then
  2590. InputElement.Readonly:=FReadOnly;
  2591. end;
  2592. procedure TCustomInputWidget.SetRequired(AValue: Boolean);
  2593. begin
  2594. If aValue=Required then exit;
  2595. FRequired:=aValue;
  2596. if IsRendered then
  2597. InputElement.Required:=FRequired;
  2598. end;
  2599. procedure TCustomInputWidget.SetText(AValue: String);
  2600. Var
  2601. Inp : TJSHTMLElement;
  2602. begin
  2603. Writeln('Setting text: ',AValue,' previous : ',Text);
  2604. if aValue=Text then exit;
  2605. FText:=aValue;
  2606. Inp:=Element;
  2607. If Assigned(Inp) then
  2608. Inp.innerText:=aValue;
  2609. end;
  2610. procedure TCustomInputWidget.SetValue(AValue: String);
  2611. Var
  2612. Inp : TJSHTMLInputElement;
  2613. begin
  2614. if aValue=Value then exit;
  2615. FValue:=aValue;
  2616. Inp:=InputElement;
  2617. If Assigned(Inp) then
  2618. Inp.value:=aValue;
  2619. end;
  2620. procedure TCustomInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2621. var
  2622. Inp : TJSHTMLInputElement absolute aElement;
  2623. begin
  2624. Inherited;
  2625. if (ExternalElement) and (FValue='') then
  2626. FValue:=TJSHTMLInputElement(aElement).value
  2627. else
  2628. begin
  2629. Inp._type:=InputType;
  2630. Inp.name:=FValueName;
  2631. Inp.value:=FValue;
  2632. Inp.Required:=FRequired;
  2633. Inp.ReadOnly:=FReadOnly;
  2634. Writeln('Setting inner text to "',FText,'"');
  2635. Inp.innerHtml:=FText;
  2636. Writeln('Setting inner text is now "',Inp.innerText,'"');
  2637. end;
  2638. end;
  2639. function TCustomInputWidget.HTMLTag: String;
  2640. begin
  2641. Result:='input';
  2642. end;
  2643. function TCustomInputWidget.GetInputElement: TJSHTMLInputElement;
  2644. begin
  2645. Result:=TJSHTMLInputElement(Element);
  2646. end;
  2647. procedure TCustomInputWidget.SetValueName(AValue: String);
  2648. Var
  2649. Inp : TJSHTMLInputElement;
  2650. begin
  2651. if aValue=ValueName then exit;
  2652. FValueName:=aValue;
  2653. Inp:=InputElement;
  2654. If Assigned(Inp) then
  2655. Inp.name:=aValue;
  2656. end;
  2657. procedure TCustomInputWidget.SetName(const NewName: TComponentName);
  2658. Var
  2659. Old : String;
  2660. begin
  2661. Old:=Name;
  2662. inherited SetName(NewName);
  2663. if (Value=Old) then
  2664. Value:=NewName;
  2665. end;
  2666. { TCustomTagWidget }
  2667. procedure TCustomTagWidget.SetElementTag(AValue: THTMLElementTag);
  2668. begin
  2669. if FElementTag=AValue then Exit;
  2670. FElementTag:=AValue;
  2671. if IsRendered then
  2672. Refresh;
  2673. end;
  2674. procedure TCustomTagWidget.SetTextContent(AValue: String);
  2675. begin
  2676. if FTextContent=AValue then Exit;
  2677. FTextContent:=AValue;
  2678. if IsRendered then
  2679. Refresh;
  2680. end;
  2681. procedure TCustomTagWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2682. begin
  2683. inherited ApplyWidgetSettings(aElement);
  2684. if FTextContent<>'' then
  2685. aElement.InnerText:=TextContent;
  2686. end;
  2687. function TCustomTagWidget.HTMLTag: String;
  2688. begin
  2689. Result:=HTMLTagNames[ElementTag];
  2690. end;
  2691. { TDivWidget }
  2692. constructor TDivWidget.Create(aOwner: TComponent);
  2693. begin
  2694. inherited Create(aOwner);
  2695. ElementTag:=etDiv;
  2696. end;
  2697. constructor TParagraphWidget.Create(aOwner: TComponent);
  2698. begin
  2699. inherited Create(aOwner);
  2700. ElementTag:=etP;
  2701. end;
  2702. end.