2
0

htmlwidgets.pp 80 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179
  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 GetDisplayName: string; override;
  576. function GetCaption: String; virtual;
  577. Public
  578. Procedure Assign(Source : TPersistent); override;
  579. Property Alignment : TAlignment Read FAlignment Write SetAlignment;
  580. Property Caption : String Read GetCaption Write SetCaption;
  581. Property ClassNames : String Read FClassNames Write SetClassNames;
  582. end;
  583. { TCustomTableColumns }
  584. TCustomTableColumns = Class(TCollection)
  585. private
  586. function GetCustomColumn(Index : Integer): TCustomTableColumn;
  587. procedure SetCustomColumn(Index : Integer; AValue: TCustomTableColumn);
  588. Protected
  589. Property CustomColumns [Index : Integer] : TCustomTableColumn Read GetCustomColumn Write SetCustomColumn; default;
  590. Public
  591. Function Add(aCaption : String): TCustomTableColumn; overload;
  592. end;
  593. { TCustomTableWidget }
  594. TTableOption = (toHeader, // use THead tag
  595. toHeaderRow, // Create header row
  596. toBody, // use TBody tag
  597. toFooter, // use TFoot tag
  598. toFooterRow, // create footer row
  599. toRowID, // add ID to tr: -kind-row
  600. toCellID, // add ID to cell td: -kind-row-col
  601. toHeaderRowData, // Add rowno to <tr data-row> for header.
  602. toHeaderCellDataRow, // Add rowno to <th data-row> for header. Automatic if onheadercellclick is set.
  603. toHeaderCellDataCol, // Add colno to <th data-col> for header. Automatic if onheadercellclick is set.
  604. toBodyRowData, // Add rowno to <tr data-row> for body.
  605. toBodyCellDataRow, // Add rowno to <th data-row> for body. Automatic if oncellclick is set.
  606. toBodyCellDataCol, // Add colno to <th data-col> for body. Automatic if oncellclick is set.
  607. tofooterRowData, // Add rowno to <tr data-row> for footer
  608. tofooterCellDataRow, // Add rowno to <th data-row> for footer. Automatic if onfootercellclick is set.
  609. tofooterCellDataCol // Add colno to <th data-col> for footer. Automatic if onfootercellclick is set.
  610. );
  611. TTableOptions = Set of TTableOption;
  612. TRowKind = (rkHeader,rkBody,rkFooter);
  613. Type
  614. TCustomTableWidget = Class;
  615. // Constructed only once when rendering !
  616. { TTableWidgetCelldata }
  617. TTableWidgetCellData = Class
  618. private
  619. FAsHTML: Boolean;
  620. FClassNames: String;
  621. FCol: Integer;
  622. FColumn: TCustomTableColumn;
  623. FContent: TJSHTMLElement;
  624. FKind: TRowKind;
  625. FRow: Integer;
  626. FTable: TCustomTableWidget;
  627. FTableID: String;
  628. FTag: String;
  629. FText: String;
  630. FWidget: TWebWidget;
  631. Protected
  632. Procedure SetRowColKind(aRow,aCol : Integer; aKind : TRowKind); virtual;
  633. Procedure Reset; // do not reset row,col, column
  634. Public
  635. Constructor Create(aTable : TCustomTableWidget;aTableID : String); virtual;
  636. Property Table : TCustomTableWidget Read FTable;
  637. Property Column : TCustomTableColumn Read FColumn;
  638. Property Row : Integer Read FRow;
  639. Property Col : Integer Read FCol;
  640. Property Kind : TRowKind Read FKind;
  641. Property Tag : String Read FTag Write FTag;
  642. Property ClassNames : String Read FClassNames Write FClassNames;
  643. Property Text : String Read FText Write FText;
  644. Property AsHTML : Boolean Read FAsHTML Write FAsHTML;
  645. Property Content : TJSHTMLElement Read FContent Write FContent;
  646. Property Widget : TWebWidget Read FWidget Write FWidget;
  647. Property TableID : String Read FTableID;
  648. end;
  649. TTableRowEnumerator = Class
  650. private
  651. FTable: TCustomTableWidget;
  652. FCurrent : Integer;
  653. public
  654. constructor Create(ATable : TCustomTableWidget); reintroduce; virtual;
  655. Procedure GetCellData(aCell : TTableWidgetCellData); virtual;
  656. function MoveNext: Boolean; virtual;
  657. property CurrentRow : Integer Read FCurrent;
  658. Property Table : TCustomTableWidget Read FTable;
  659. end;
  660. TTableRowCountEnumerator = Class (TTableRowEnumerator)
  661. private
  662. FRowCount: Integer;
  663. public
  664. constructor Create(ATable : TCustomTableWidget;aCount : Integer); reintroduce;
  665. function MoveNext: Boolean; override;
  666. Property RowCount : Integer read FRowCount;
  667. end;
  668. TOnCellDataEvent = Procedure (Sender : TObject; Enum : TTableRowEnumerator; aCell : TTableWidgetCellData) of object;
  669. TCustomTableWidget = Class(TCustomWebWidget)
  670. private
  671. FCaption: String;
  672. FColumns: TCustomTableColumns;
  673. FOnCellClick: THTMLNotifyEvent;
  674. FOnFooterCellClick: THTMLNotifyEvent;
  675. FOnFooterRowClick: THTMLNotifyEvent;
  676. FOnHeaderCellClick: THTMLNotifyEvent;
  677. FOnHeaderRowClick: THTMLNotifyEvent;
  678. FOnRowClick: THTMLNotifyEvent;
  679. FTableOptions: TTableOptions;
  680. FOnGetCellData : TOnCellDataEvent;
  681. FWidgets : Array of TWebWidget;
  682. FUpdateCount : Integer;
  683. procedure SetCaption(AValue: String);
  684. procedure SetColumns(AValue: TCustomTableColumns);
  685. procedure SetTableOptions(AValue: TTableOptions);
  686. Protected
  687. procedure AppendCaption(aCaptionElement: TJSHTMLElement); virtual;
  688. procedure RenderData(aElement: TJSHTMLElement); virtual;
  689. function DoCellClick(aEvent: TJSMouseEvent): boolean; virtual;
  690. function DoHeaderCellClick(aEvent: TJSMouseEvent): boolean;virtual;
  691. function DoFooterCellClick(aEvent: TJSMouseEvent): boolean;virtual;
  692. function DoRowClick(aEvent: TJSMouseEvent): boolean; virtual;
  693. function DoHeaderRowClick(aEvent: TJSMouseEvent): boolean;virtual;
  694. function DoFooterRowClick(aEvent: TJSMouseEvent): boolean;virtual;
  695. function CreateColumns: TCustomTableColumns; virtual;
  696. Function DefaultTableOptions: TTableOptions; virtual;
  697. Procedure CreateDefaultColumns; virtual;
  698. Function GetRowEnumerator(aKind : TRowKind) : TTableRowEnumerator; virtual;
  699. function RenderCell(aCell: TTableWidgetCellData): TJSHTMLElement; virtual;
  700. procedure RenderRow(aEnum : TTableRowEnumerator; aParent: TJSHTMLElement; aKind: TRowKind; aCell: TTableWidgetCellData); virtual;
  701. procedure RenderRows(aParent: TJSHTMLElement; aKind : TRowKind; aCell: TTableWidgetCellData); virtual;
  702. Procedure ApplyWidgetSettings(aElement : TJSHTMLElement); override;
  703. Function HTMLTag : String; override;
  704. Function CreateCellData(const aTableID : String) : TTableWidgetCellData; virtual;
  705. Function GetBodyRowEnumerator : TTableRowEnumerator; virtual; abstract;
  706. Protected
  707. // These can be made public/published
  708. Property CustomColumns : TCustomTableColumns Read FColumns Write SetColumns;
  709. Property TableOptions : TTableOptions read FTableOptions write SetTableOptions;
  710. Property Caption : String Read FCaption Write SetCaption;
  711. Property OnGetCellData : TOnCellDataEvent Read FOnGetCellData Write FOnGetCellData;
  712. Property OnCellClick : THTMLNotifyEvent Read FOnCellClick Write FOnCellClick;
  713. Property OnHeaderCellClick : THTMLNotifyEvent Read FOnHeaderCellClick Write FOnHeaderCellClick;
  714. Property OnFooterCellClick : THTMLNotifyEvent Read FOnFooterCellClick Write FOnFooterCellClick;
  715. Property OnRowClick : THTMLNotifyEvent Read FOnRowClick Write FOnRowClick;
  716. Property OnHeaderRowClick : THTMLNotifyEvent Read FOnHeaderRowClick Write FOnHeaderRowClick;
  717. Property OnFooterRowClick : THTMLNotifyEvent Read FOnFooterRowClick Write FOnFooterRowClick;
  718. Public
  719. Constructor Create(aOwner : TComponent); override;
  720. Destructor Destroy; override;
  721. Procedure BeginUpdate;
  722. Procedure EndUpdate;
  723. Procedure RefreshBody;
  724. end;
  725. { TEventTableWidget }
  726. TEventTableWidget = Class(TCustomTableWidget)
  727. private
  728. FRowCount: Integer;
  729. procedure SetRowCount(AValue: Integer);
  730. Protected
  731. Function GetBodyRowEnumerator : TTableRowEnumerator; override;
  732. Published
  733. Property RowCount : Integer Read FRowCount Write SetRowCount;
  734. Property CustomColumns;
  735. Property TableOptions;
  736. Property Caption;
  737. Property OnGetCellData;
  738. Property OnCellClick;
  739. Property OnHeaderCellClick;
  740. Property OnFooterCellClick;
  741. Property OnRowClick;
  742. Property OnHeaderRowClick;
  743. Property OnFooterRowClick;
  744. end;
  745. { TCustomStringsTableWidget }
  746. TCustomStringsTableWidget = Class(TCustomTableWidget)
  747. private
  748. Type
  749. TRow = Array of string;
  750. private
  751. FRows : Array of TRow;
  752. function GetRowCount: Integer;
  753. procedure SetRowCount(AValue: Integer);
  754. Protected
  755. Type
  756. TStringRowsEnumerator = Class(TTableRowCountEnumerator)
  757. Procedure GetCellData(aCell : TTableWidgetCellData); override;
  758. end;
  759. Protected
  760. Procedure CheckIndex(aCol,aRow : Integer);
  761. function GetCell(aCol, aRow : integer): String;
  762. procedure SetCell(aCol, aRow : integer; AValue: String);
  763. Function GetBodyRowEnumerator : TTableRowEnumerator; override;
  764. Public
  765. Property RowCount : Integer Read GetRowCount Write SetRowCount;
  766. Property Cells[aCol,aRow : integer] : String Read GetCell Write SetCell;
  767. Property CustomColumns;
  768. Property TableOptions;
  769. Property Caption;
  770. Property OnGetCellData;
  771. Property OnCellClick;
  772. Property OnHeaderCellClick;
  773. Property OnFooterCellClick;
  774. Property OnRowClick;
  775. Property OnHeaderRowClick;
  776. Property OnFooterRowClick;
  777. end;
  778. TStringsTableWidget = Class(TCustomStringsTableWidget)
  779. Published
  780. Property RowCount;
  781. Property CustomColumns;
  782. Property TableOptions;
  783. Property Caption;
  784. Property OnGetCellData;
  785. Property OnCellClick;
  786. Property OnHeaderCellClick;
  787. Property OnFooterCellClick;
  788. Property OnRowClick;
  789. Property OnHeaderRowClick;
  790. Property OnFooterRowClick;
  791. end;
  792. { TDivWidget }
  793. THTMLElementTag = (
  794. etUnknown, eta, etabbr, etacronym, etaddress, etapplet, etarea, etb, etbase,
  795. etbasefont, etbdo, etbig, etblockquote, etbody, etbr, etbutton,
  796. etcaption, etcenter, etcite, etcode, etcol, etcolgroup, etdd, etdel,
  797. etdfn, etdir, etdiv, etdl, etdt, etem, etfieldset, etfont, etform,
  798. etframe, etframeset, eth1, eth2, eth3, eth4, eth5, eth6, ethead, ethr,
  799. ethtml, eti, etiframe, etimg, etinput, etins, etisindex, etkbd, etlabel,
  800. etlegend, etli, etlink, etmap, etmenu, etmeta, etnoframes, etnoscript,
  801. etobject, etol, etoptgroup, etoption, etp, etparam, etpre, etq, ets,
  802. etsamp, etscript, etselect, etsmall, etspan, etstrike, etstrong,
  803. etstyle, etsub, etsup, ettable, ettbody, ettd, ettextarea, ettfoot,
  804. etth, etthead, ettitle, ettr, ettt, etu, etul, etvar,
  805. etText,etAudio,etVideo,etSource
  806. );
  807. THTMLElementTagSet = set of THTMLElementTag;
  808. { TCustomTagWidget }
  809. TCustomTagWidget = Class(TWebWidget)
  810. private
  811. FElementTag: THTMLElementTag;
  812. FTextContent: String;
  813. procedure SetElementTag(AValue: THTMLElementTag);
  814. procedure SetTextContent(AValue: String);
  815. Protected
  816. Procedure ApplyWidgetSettings(aElement: TJSHTMLElement); override;
  817. Function HTMLTag : String; override;
  818. // Set tag you wish to use
  819. Property elementTag : THTMLElementTag Read FElementTag Write SetElementTag;
  820. // If set, the text will be set as InnerText of the tag
  821. Property TextContent : String Read FTextContent Write SetTextContent;
  822. end;
  823. { TTagWidget }
  824. TTagWidget = Class(TCustomTagWidget)
  825. Public
  826. Constructor Create(aOwner : TComponent); override;
  827. Published
  828. Property elementTag;
  829. Property TextContent;
  830. end;
  831. TDivWidget = Class(TCustomTagWidget)
  832. Public
  833. Constructor Create(aOwner : TComponent); override;
  834. end;
  835. { TParagraphWidget }
  836. TParagraphWidget = Class(TCustomTagWidget)
  837. Public
  838. Constructor Create(aOwner : TComponent); override;
  839. end;
  840. { TMediaWidget }
  841. TMediaWidget = Class(TCustomTagWidget)
  842. private
  843. Const
  844. MaxAttrs = 20;
  845. PropAttrs : Array[0..MaxAttrs] of string
  846. = ('src','defaultPlaybackRate','duration','playbackRate','ended', // 0..4
  847. 'paused','seeking','sinkId','mediaGroup','currentSrc', // 5..9
  848. 'volume','controls','autoplay','crossOrigin', 'defaultMuted', // 10..14
  849. 'currentTime', 'disableRemotePlayback', 'preservesPitch','loop','muted', // 15..19
  850. 'preload' // 20
  851. );
  852. function GetAudioTrack: TJSHTMLAudioTrackList;
  853. function getBool(AIndex: Integer): Boolean;
  854. function GetError: TJSMEdiaError;
  855. function getFloat(AIndex: Integer): Double;
  856. function GetSrcObj: TJSHTMLMediaStream;
  857. function getString(AIndex: Integer): String;
  858. function GetTextTrack: TJSHTMLTextTrackList;
  859. function GetVideoTrack: TJSHTMLVideoTrackList;
  860. procedure SetBool(AIndex: Integer; AValue: Boolean);
  861. procedure SetFloat(AIndex: Integer; AValue: Double);
  862. procedure SetString(AIndex: Integer; AValue: String);
  863. function getEl: TJSObject;
  864. Public
  865. Property DefaultPlayBackRate : Double Index 1 Read getFloat;
  866. Property Duration : Double Index 2 Read getFloat;
  867. Property PlayBackRate : Double Index 3 Read getFloat;
  868. Property Ended : Boolean Index 4 Read getBool;
  869. Property Paused : Boolean Index 5 Read getBool;
  870. Property Seeking : Boolean Index 6 Read getBool;
  871. Property SinkID : String Index 7 Read getString Write SetString;
  872. Property MediaGroup : String Index 8 Read getString Write SetString;
  873. Property SrcObject : TJSHTMLMediaStream Read GetSrcObj;
  874. Property textTracks : TJSHTMLTextTrackList Read GetTextTrack;
  875. Property videoTracks : TJSHTMLVideoTrackList Read GetVideoTrack;
  876. Property audioTracks : TJSHTMLAudioTrackList Read GetAudioTrack;
  877. Property Error : TJSMEdiaError Read GetError;
  878. Property CurrentSrc : String Index 9 Read getString;
  879. Published
  880. Property Src : String Index 0 Read getString Write SetString;
  881. Property Controls : Boolean Index 11 Read getBool Write SetBool;
  882. Property AutoPlay : Boolean Index 12 Read getBool Write SetBool;
  883. Property CrossOrigin : String index 13 Read getString Write SetString;
  884. Property DefaultMuted : Boolean Index 14 Read getBool Write SetBool;
  885. Property CurrentTime : Double Index 15 Read getFloat Write SetFloat;
  886. Property DisableRemotePlayback : Boolean Index 16 Read getBool Write SetBool;
  887. Property PreservesPitch : Boolean Index 17 Read getBool Write SetBool;
  888. Property Loop : Boolean Index 18 Read getBool Write SetBool;
  889. Property Muted : Boolean Index 19 Read getBool Write SetBool;
  890. Property Preload : String Index 20 Read getString Write SetString;
  891. Property Volume : Double Index 10 Read getFloat Write SetFloat;
  892. end;
  893. { TVideoWidget }
  894. TVideoWidget = Class(TMediaWidget)
  895. Public
  896. Constructor Create(aOwner : TComponent); override;
  897. end;
  898. { TAudioWidget }
  899. TAudioWidget = Class(TMediaWidget)
  900. Public
  901. Constructor Create(aOwner : TComponent); override;
  902. end;
  903. Function ViewPort : TViewPort;
  904. Const
  905. TextTagNames : Array[TTextTag] of string
  906. = ('p','b','i','u','s','span','quote','blockquote','h1','h2','h3','h4','h5','h6','pre','ruby','article','address','abbr','');
  907. RowKindNames : Array[TRowKind] of string = ('header','body','footer');
  908. HTMLTagNames : Array[THTMLElementTag] of string = (
  909. '?', 'a', 'abbr', 'acronym', 'address', 'applet', 'area', 'b', 'base',
  910. 'basefont', 'bdo', 'big', 'blockquote', 'body', 'br', 'button',
  911. 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'dd', 'del',
  912. 'dfn', 'dir', 'div', 'dl', 'dt', 'em', 'fieldset', 'font', 'form',
  913. 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr',
  914. 'html', 'i', 'iframe', 'img', 'input', 'ins', 'isindex', 'kbd', 'label',
  915. 'legend', 'li', 'link', 'map', 'menu', 'meta', 'noframes', 'noscript',
  916. 'object', 'ol', 'optgroup', 'option', 'p', 'param', 'pre', 'q', 's',
  917. 'samp', 'script', 'select', 'small', 'span', 'strike', 'strong',
  918. 'style', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot',
  919. 'th', 'thead', 'title', 'tr', 'tt', 'u', 'ul', 'var',
  920. 'Text','Audio','Video','Source'
  921. );
  922. implementation
  923. uses DateUtils;
  924. resourcestring
  925. SErrInvalidIndex = 'Index %d not in valid range of [0..%d]';
  926. SErrInvalidRowCount = 'Invalid row count: %d';
  927. SRow = 'Row';
  928. SCol = 'Column';
  929. Function ViewPort : TViewPort;
  930. begin
  931. Result:=TViewPort.Instance;
  932. end;
  933. { TTableRowCountEnumerator }
  934. Const
  935. CellTags : Array[TRowKind] of string = ('th','td','td');
  936. { TEventTableWidget }
  937. procedure TEventTableWidget.SetRowCount(AValue: Integer);
  938. begin
  939. if FRowCount=AValue then Exit;
  940. BeginUpdate;
  941. FRowCount:=AValue;
  942. EndUpdate;
  943. end;
  944. function TEventTableWidget.GetBodyRowEnumerator: TTableRowEnumerator;
  945. begin
  946. Result:=TTableRowCountEnumerator.Create(Self,RowCount);
  947. end;
  948. { TCustomStringsTableWidget.TStringRowsEnumerator }
  949. procedure TCustomStringsTableWidget.TStringRowsEnumerator.GetCellData(aCell: TTableWidgetCellData);
  950. begin
  951. aCell.Text:=TCustomStringsTableWidget(Table).Cells[aCell.Col,aCell.Row];
  952. end;
  953. { TCustomStringsTableWidget }
  954. function TCustomStringsTableWidget.GetCell(aCol, aRow : integer): String;
  955. begin
  956. CheckIndex(aCol,aRow);
  957. Result:=FRows[aRow][aCol];
  958. end;
  959. function TCustomStringsTableWidget.GetRowCount: Integer;
  960. begin
  961. Result:=Length(FRows);
  962. end;
  963. procedure TCustomStringsTableWidget.SetCell(aCol, aRow : integer; AValue: String);
  964. begin
  965. CheckIndex(aCol,aRow);
  966. BeginUpdate;
  967. try
  968. FRows[aRow][aCol]:=AValue;
  969. Finally
  970. EndUpdate;
  971. end;
  972. end;
  973. function TCustomStringsTableWidget.GetBodyRowEnumerator: TTableRowEnumerator;
  974. begin
  975. Result:=TStringRowsEnumerator.Create(Self,RowCount);
  976. end;
  977. procedure TCustomStringsTableWidget.SetRowCount(AValue: Integer);
  978. begin
  979. if AValue<0 then
  980. raise EWidgets.CreateFmt(SerrInvalidRowCount, [aValue]);
  981. BeginUpdate;
  982. try
  983. SetLength(FRows,aValue);
  984. Finally
  985. EndUpdate;
  986. end;
  987. end;
  988. procedure TCustomStringsTableWidget.CheckIndex(aCol, aRow: Integer);
  989. begin
  990. If (aCol<0) or (aCol>=CustomColumns.Count) then
  991. Raise EWidgets.CreateFmt(SCol+' '+SErrInvalidIndex,[aCol,0,CustomColumns.Count-1]);
  992. If (aRow<0) or (aRow>=RowCount) then
  993. Raise EWidgets.CreateFmt(SRow+' '+SErrInvalidIndex,[aRow,0,RowCount-1]);
  994. end;
  995. { TTagWidget }
  996. constructor TTagWidget.Create(aOwner: TComponent);
  997. begin
  998. inherited Create(aOwner);
  999. ElementTag:=etdiv;
  1000. end;
  1001. { TMediaWidget }
  1002. function TMediaWidget.GetAudioTrack: TJSHTMLAudioTrackList;
  1003. begin
  1004. if Assigned(Element) then
  1005. Result:=TJSHTMLMediaElement(Element).AudioTracks
  1006. else
  1007. Result:=Nil;
  1008. end;
  1009. function TMediaWidget.getBool(AIndex: Integer): Boolean;
  1010. Var
  1011. El : TJSObject;
  1012. Att : String;
  1013. begin
  1014. El:=GetEl;
  1015. Att:=PropAttrs[aIndex];
  1016. Result:=Assigned(el) and isDefined(El[Att]) and (Boolean(El[Att]));
  1017. end;
  1018. function TMediaWidget.GetError: TJSMEdiaError;
  1019. begin
  1020. If Assigned(Element) then
  1021. Result:=TJSHTMLMediaElement(Element).Error
  1022. else
  1023. Result:=Nil;
  1024. end;
  1025. function TMediaWidget.getFloat(AIndex: Integer): Double;
  1026. Var
  1027. El : TJSObject;
  1028. Att : String;
  1029. begin
  1030. El:=GetEl;
  1031. Att:=PropAttrs[aIndex];
  1032. if Assigned(el) and isDefined(El[Att]) then
  1033. Result:=Double(El[Att])
  1034. else
  1035. Result:=0;
  1036. end;
  1037. function TMediaWidget.GetSrcObj: TJSHTMLMediaStream;
  1038. begin
  1039. If Assigned(Element) then
  1040. Result:=TJSHTMLMediaElement(Element).srcObject
  1041. else
  1042. Result:=Nil;
  1043. end;
  1044. function TMediaWidget.getString(AIndex: Integer): String;
  1045. Var
  1046. El : TJSObject;
  1047. Att : String;
  1048. begin
  1049. El:=GetEl;
  1050. Att:=PropAttrs[aIndex];
  1051. if Assigned(el) and isDefined(El[Att]) then
  1052. Result:=String(El[Att])
  1053. else
  1054. Result:='';
  1055. end;
  1056. function TMediaWidget.GetTextTrack: TJSHTMLTextTrackList;
  1057. begin
  1058. If Assigned(Element) then
  1059. Result:=TJSHTMLMediaElement(Element).TextTracks
  1060. else
  1061. Result:=Nil;
  1062. end;
  1063. function TMediaWidget.GetVideoTrack: TJSHTMLVideoTrackList;
  1064. begin
  1065. If Assigned(Element) then
  1066. Result:=TJSHTMLMediaElement(Element).VideoTracks
  1067. else
  1068. Result:=Nil;
  1069. end;
  1070. procedure TMediaWidget.SetBool(AIndex: Integer; AValue: Boolean);
  1071. Var
  1072. El : TJSObject;
  1073. Att : String;
  1074. begin
  1075. El:=GetEl;
  1076. Att:=PropAttrs[aIndex];
  1077. if Assigned(el) then
  1078. El[Att]:=aValue
  1079. else
  1080. Attrs[Att]:=IntToStr(Ord(AValue));
  1081. end;
  1082. procedure TMediaWidget.SetFloat(AIndex: Integer; AValue: Double);
  1083. Var
  1084. El : TJSObject;
  1085. Att,S : String;
  1086. begin
  1087. El:=GetEl;
  1088. Att:=PropAttrs[aIndex];
  1089. if Assigned(el) then
  1090. El[Att]:=aValue
  1091. else
  1092. begin
  1093. Str(aValue,S);
  1094. Attrs[Att]:=S;
  1095. end;
  1096. end;
  1097. procedure TMediaWidget.SetString(AIndex: Integer; AValue: String);
  1098. Var
  1099. El : TJSObject;
  1100. Att : String;
  1101. begin
  1102. El:=GetEl;
  1103. Att:=PropAttrs[aIndex];
  1104. if Assigned(el) then
  1105. El[Att]:=aValue
  1106. else
  1107. Attrs[Att]:=aValue;
  1108. end;
  1109. function TMediaWidget.getEl: TJSObject;
  1110. begin
  1111. Result:=Element;
  1112. if Not Assigned(Result) then
  1113. Result:=Self.StoredAttrs;
  1114. end;
  1115. { TVideoWidget }
  1116. constructor TVideoWidget.Create(aOwner: TComponent);
  1117. begin
  1118. inherited Create(aOwner);
  1119. elementTag:=etVideo;
  1120. end;
  1121. { TAudioWidget }
  1122. constructor TAudioWidget.Create(aOwner: TComponent);
  1123. begin
  1124. inherited Create(aOwner);
  1125. elementTag:=etAudio;
  1126. end;
  1127. { TSelectWidget.TStringsSelectOptionEnumerator }
  1128. constructor TSelectWidget.TStringsSelectOptionEnumerator.Create(ASelect: TCustomSelectWidget);
  1129. begin
  1130. inherited Create(ASelect);
  1131. FCurrent:=-1;
  1132. end;
  1133. function TSelectWidget.TStringsSelectOptionEnumerator.OptionText: String;
  1134. begin
  1135. Result:=TSelectWidget(Select).Items[FCurrent];
  1136. end;
  1137. function TSelectWidget.TStringsSelectOptionEnumerator.HasValue: boolean;
  1138. begin
  1139. Result:=FCurrent<TSelectWidget(Select).Values.Count;
  1140. end;
  1141. function TSelectWidget.TStringsSelectOptionEnumerator.Value: string;
  1142. begin
  1143. Result:=TSelectWidget(Select).Values[FCurrent];
  1144. end;
  1145. function TSelectWidget.TStringsSelectOptionEnumerator.MoveNext: Boolean;
  1146. begin
  1147. Result:=FCurrent<TSelectWidget(Select).Items.Count-1;
  1148. if Result then
  1149. Inc(FCurrent);
  1150. end;
  1151. { TCustomSelectWidget.TSelectOptionEnumerator }
  1152. constructor TCustomSelectWidget.TSelectOptionEnumerator.Create(ASelect: TCustomSelectWidget);
  1153. begin
  1154. FSelect:=ASelect;
  1155. end;
  1156. function TCustomSelectWidget.TSelectOptionEnumerator.HasValue: boolean;
  1157. begin
  1158. Result:=False;
  1159. end;
  1160. function TCustomSelectWidget.TSelectOptionEnumerator.Value: string;
  1161. begin
  1162. Result:='';
  1163. end;
  1164. constructor TTableRowCountEnumerator.Create(ATable: TCustomTableWidget; aCount: Integer);
  1165. begin
  1166. Inherited Create(aTable);
  1167. FRowCount:=aCount;
  1168. end;
  1169. function TTableRowCountEnumerator.MoveNext: Boolean;
  1170. begin
  1171. Result:=Inherited MoveNext and (CurrentRow<RowCount)
  1172. end;
  1173. { TTableWidgetCellData }
  1174. procedure TTableWidgetCellData.SetRowColKind(aRow, aCol: Integer; aKind: TRowKind);
  1175. begin
  1176. if (aRow<>-1) then
  1177. FRow:=aRow;
  1178. if (aCol<>-1) then
  1179. FCol:=aCol;
  1180. FKind:=aKind;
  1181. end;
  1182. procedure TTableWidgetCellData.Reset;
  1183. begin
  1184. Ftag:='td';
  1185. FClassNames:='';
  1186. FText:='';
  1187. FContent:=Nil;
  1188. FAsHTML:=False;
  1189. FWidget:=Nil;
  1190. end;
  1191. constructor TTableWidgetCellData.Create(aTable: TCustomTableWidget; aTableID: String);
  1192. begin
  1193. FTable:=aTable;
  1194. FTableID:=aTableID;
  1195. SetRowColKind(0,0,rkBody);
  1196. end;
  1197. { TCustomTableWidget }
  1198. procedure TCustomTableWidget.SetColumns(AValue: TCustomTableColumns);
  1199. begin
  1200. if FColumns=AValue then Exit;
  1201. FColumns.Assign(AValue);
  1202. end;
  1203. procedure TCustomTableWidget.SetCaption(AValue: String);
  1204. begin
  1205. if FCaption=AValue then Exit;
  1206. FCaption:=AValue;
  1207. if isRendered then Refresh;
  1208. end;
  1209. function TCustomTableWidget.DoCellClick(aEvent: TJSMouseEvent): boolean;
  1210. begin
  1211. If Assigned(FOnCellClick) then
  1212. FOnCellClick(Self,aEvent);
  1213. If Assigned(FOnRowClick) then
  1214. FOnRowClick(Self,aEvent);
  1215. Result:=False;
  1216. // Writeln('On click for cell',aEvent.targetElement.innerText);
  1217. end;
  1218. function TCustomTableWidget.DoHeaderCellClick(aEvent: TJSMouseEvent): boolean;
  1219. begin
  1220. If Assigned(FOnHeaderCellClick) then
  1221. FOnHeaderCellClick(Self,aEvent);
  1222. If Assigned(FOnHeaderRowClick) then
  1223. FOnHeaderRowClick(Self,aEvent);
  1224. Result:=False;
  1225. // Writeln('On click for header cell',aEvent.targetElement.innerText);
  1226. end;
  1227. function TCustomTableWidget.DoFooterCellClick(aEvent: TJSMouseEvent): boolean;
  1228. begin
  1229. If Assigned(FOnFooterCellClick) then
  1230. FOnFooterCellClick(Self,aEvent);
  1231. If Assigned(FOnFooterRowClick) then
  1232. FOnFooterRowClick(Self,aEvent);
  1233. Result:=False;
  1234. // Writeln('On click for Footer cell',aEvent.targetElement.innerText);
  1235. end;
  1236. function TCustomTableWidget.DoRowClick(aEvent: TJSMouseEvent): boolean;
  1237. begin
  1238. If Assigned(FOnRowClick) then
  1239. FOnRowClick(Self,aEvent);
  1240. Result:=False;
  1241. // Writeln('On click for Row',aEvent.targetElement.innerText);
  1242. end;
  1243. function TCustomTableWidget.DoHeaderRowClick(aEvent: TJSMouseEvent): boolean;
  1244. begin
  1245. If Assigned(FOnHeaderRowClick) then
  1246. FOnHeaderRowClick(Self,aEvent);
  1247. Result:=False;
  1248. // Writeln('On click for Header Row',aEvent.targetElement.innerText);
  1249. end;
  1250. function TCustomTableWidget.DoFooterRowClick(aEvent: TJSMouseEvent): boolean;
  1251. begin
  1252. If Assigned(FOnFooterRowClick) then
  1253. FOnFooterRowClick(Self,aEvent);
  1254. Result:=False;
  1255. // Writeln('On click for Footer Row',aEvent.targetElement.innerText);
  1256. end;
  1257. procedure TCustomTableWidget.SetTableOptions(AValue: TTableOptions);
  1258. begin
  1259. if FTableOptions=AValue then Exit;
  1260. FTableOptions:=AValue;
  1261. if IsRendered then
  1262. Refresh;
  1263. end;
  1264. procedure TCustomTableWidget.AppendCaption(aCaptionElement: TJSHTMLElement);
  1265. begin
  1266. aCaptionElement.InnerHTML:=Caption;
  1267. end;
  1268. function TCustomTableWidget.GetRowEnumerator(aKind: TRowKind): TTableRowEnumerator;
  1269. begin
  1270. Case aKind of
  1271. rkHeader : Result:=TTableRowCountEnumerator.Create(Self,1);
  1272. rkFooter : Result:=TTableRowCountEnumerator.Create(Self,1);
  1273. rkBody : Result:=GetBodyRowEnumerator;
  1274. end;
  1275. end;
  1276. procedure TTableRowEnumerator.GetCellData(aCell: TTableWidgetCellData);
  1277. Var
  1278. K : TRowKind;
  1279. begin
  1280. K:=aCell.Kind;
  1281. Case K of
  1282. rkHeader:
  1283. begin
  1284. aCell.Tag:='th';
  1285. aCell.Text:=ACell.Column.Caption;
  1286. end;
  1287. rkFooter,
  1288. rkBody :
  1289. begin
  1290. aCell.Tag:='td';
  1291. end;
  1292. end;
  1293. end;
  1294. function TCustomTableWidget.HTMLTag: String;
  1295. begin
  1296. Result:='table';
  1297. end;
  1298. function TCustomTableWidget.RenderCell(aCell: TTableWidgetCellData): TJSHTMLElement;
  1299. Const
  1300. Aligns : Array[TAlignment] of string = ('left','right','center');
  1301. RowChecks : Array[TRowKind] of TTableOption = (toHeaderCellDataRow,toBodyCellDataRow,toFooterCellDataRow);
  1302. ColChecks : Array[TRowKind] of TTableOption = (toHeaderCellDataCol,toBodyCellDataCol,toFooterCellDataCol);
  1303. Var
  1304. C : TJSHtmlElement;
  1305. cl : THTMLNotifyEvent;
  1306. K : TRowKind;
  1307. M : THTMLClickEventHandler;
  1308. elID : string;
  1309. begin
  1310. K:=aCell.Kind;
  1311. if (toCellID in TableOptions) or Assigned(aCell.Widget) then
  1312. elID:=aCell.TableID+'-'+RowKindNames[K]+'-'+IntToStr(ACell.Row)+'-'+IntToStr(aCell.Col)
  1313. else
  1314. elID:='';
  1315. C:=CreateElement(aCell.Tag,elID);
  1316. if aCell.Widget<>Nil then
  1317. aCell.Widget.ParentID:=elID;
  1318. if aCell.Content<>Nil then
  1319. C.AppendChild(aCell.Content)
  1320. else if aCell.AsHTML then
  1321. C.innerHTML:=aCell.text
  1322. else
  1323. C.innerText:=aCell.text;
  1324. C.className:=AddClasses(aCell.Column.ClassNames,aCell.ClassNames);
  1325. if ACell.Column.Alignment<>taLeftJustify then
  1326. C.Style.setProperty('text-align',Aligns[ACell.Column.Alignment]);
  1327. Case K of
  1328. rkBody :
  1329. begin
  1330. CL:=FOnCellClick;
  1331. M:=@DoCellClick;
  1332. end;
  1333. rkHeader :
  1334. begin
  1335. CL:=FOnHeaderCellClick;
  1336. M:=@DoHeaderCellClick;
  1337. end;
  1338. rkFooter :
  1339. begin
  1340. CL:=FOnFooterCellClick;
  1341. M:=@DoFooterCellClick;
  1342. end;
  1343. else
  1344. CL:=Nil;
  1345. M:=nil;
  1346. end;
  1347. if Assigned(cl) or (RowChecks[K] in TableOptions) then
  1348. begin
  1349. C.dataset['row']:=ACell.Row;
  1350. C.Dataset['kind']:=RowKindNames[K];
  1351. end;
  1352. if Assigned(cl) or (ColChecks[K] in TableOptions) then
  1353. begin
  1354. C.dataset['col']:=ACell.Col;
  1355. C.Dataset['kind']:=RowKindNames[K];
  1356. end;
  1357. if Assigned(M) then
  1358. C.OnClick:=M;
  1359. if aCell.Widget<>Nil then
  1360. TJSArray(FWidgets).Push(aCell.Widget);
  1361. Result:=C;
  1362. end;
  1363. procedure TCustomTableWidget.RenderRow(aEnum: TTableRowEnumerator; aParent: TJSHTMLElement; aKind: TRowKind; aCell: TTableWidgetCellData);
  1364. Var
  1365. I: integer;
  1366. begin
  1367. For I:=0 to CustomColumns.Count-1 do
  1368. begin
  1369. aCell.Reset;
  1370. aCell.FColumn:=CustomColumns[i];
  1371. aCell.SetRowColKind(-1,I,aKind);
  1372. // Writeln(CellKinds[aKind],' cell before : ',aCell.Tag,' data : ',aCell.Text);
  1373. aEnum.GetCellData(aCell);
  1374. // Writeln(CellKinds[aKind],' cell after : ',aCell.Tag,' data : ',aCell.Text);
  1375. if aCell.Tag='' then
  1376. ACell.Tag:=CellTags[aKind];
  1377. if Assigned(FOnGetCellData) then
  1378. FOnGetCellData(Self,aEnum,aCell);
  1379. aParent.appendChild(RenderCell(aCell));
  1380. end;
  1381. end;
  1382. procedure TCustomTableWidget.RenderRows(aParent: TJSHTMLElement; aKind: TRowKind; aCell: TTableWidgetCellData);
  1383. Const
  1384. TableRowChecks : Array[TRowKind] of TTableOption = (toHeaderRowData,toBodyRowData,toFooterRowData);
  1385. Var
  1386. RowEl : TJSHTMLElement;
  1387. Enum : TTableRowEnumerator;
  1388. M : THTMLClickEventHandler;
  1389. cl : THTMLNotifyEvent;
  1390. elid : String;
  1391. begin
  1392. Enum:=GetRowEnumerator(aKind);
  1393. if Enum=Nil then
  1394. Exit;
  1395. try
  1396. While Enum.MoveNext do
  1397. begin
  1398. if toRowID in TableOptions then
  1399. elID:=aCell.TableID+'-'+RowKindNames[aKind]+'-'+IntToStr(Enum.CurrentRow)
  1400. else
  1401. elID:='';
  1402. RowEl:=CreateElement('tr',elID);
  1403. aCell.SetRowColKind(Enum.CurrentRow,-1,aKind);
  1404. Case aKind of
  1405. rkBody :
  1406. begin
  1407. CL:=FOnRowClick;
  1408. M:=@DoRowClick;
  1409. end;
  1410. rkHeader :
  1411. begin
  1412. CL:=FOnHeaderRowClick;
  1413. M:=@DoHeaderRowClick;
  1414. end;
  1415. rkFooter :
  1416. begin
  1417. CL:=FOnFooterRowClick;
  1418. M:=@DoFooterRowClick;
  1419. end;
  1420. end;
  1421. if Assigned(CL) or (TableRowChecks[Akind] in TableOptions) then
  1422. begin
  1423. RowEl.dataset['row']:=Enum.CurrentRow;
  1424. RowEl.dataset['kind']:=RowKindNames[aKind];
  1425. end;
  1426. if Assigned(M) then
  1427. RowEl.OnClick:=M;
  1428. RenderRow(Enum,RowEl,aKind,aCell);
  1429. aParent.AppendChild(RowEl);
  1430. end;
  1431. finally
  1432. Enum.Free;
  1433. end;
  1434. end;
  1435. procedure TCustomTableWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1436. begin
  1437. inherited ApplyWidgetSettings(aElement);
  1438. RenderData(aElement);
  1439. end;
  1440. procedure TCustomTableWidget.RenderData(aElement: TJSHTMLElement);
  1441. Var
  1442. El : TJSHTMLElement;
  1443. aCell : TTableWidgetCellData;
  1444. W : TWebWidget;
  1445. begin
  1446. FWidgets:=[];
  1447. if (Caption<>'') then
  1448. begin
  1449. El:=CreateElement('caption',aElement.ID+'-caption');
  1450. AppendCaption(EL);
  1451. aElement.AppendChild(EL);
  1452. end;
  1453. aCell:=CreateCellData(aElement.ID);
  1454. If (CustomColumns.Count=0) then
  1455. CreateDefaultColumns;
  1456. if toHeaderRow in TableOptions then
  1457. begin
  1458. if toHeader in TableOptions then
  1459. begin
  1460. El:=CreateElement('thead',aElement.ID+'-head');
  1461. aElement.AppendChild(el);
  1462. end
  1463. else
  1464. El:=aElement;
  1465. aCell.SetRowColKind(-1,-1,rkHeader);
  1466. RenderRows(El,rkHeader,aCell);
  1467. end;
  1468. if toBody in TableOptions then
  1469. begin
  1470. El:=CreateElement('tbody',aElement.ID+'-body');
  1471. aElement.AppendChild(el);
  1472. end
  1473. else
  1474. El:=aElement;
  1475. aCell.SetRowColKind(-1,-1,rkBody);
  1476. RenderRows(El,rkBody,aCell);
  1477. if toFooterRow in TableOptions then
  1478. begin
  1479. if toFooter in TableOptions then
  1480. begin
  1481. El:=CreateElement('tFoot',aElement.ID+'-foot');
  1482. aElement.AppendChild(el);
  1483. end
  1484. else
  1485. El:=aElement;
  1486. aCell.SetRowColKind(-1,-1,rkFooter);
  1487. RenderRows(El,rkFooter,aCell);
  1488. end;
  1489. for W in FWidgets do
  1490. W.Refresh;
  1491. FWidgets:=[];
  1492. end;
  1493. function TCustomTableWidget.CreateCellData(const aTableID : String): TTableWidgetCellData;
  1494. begin
  1495. Result:=TTableWidgetCellData.Create(Self,aTableID);
  1496. end;
  1497. function TCustomTableWidget.CreateColumns: TCustomTableColumns;
  1498. begin
  1499. Result:=TCustomTableColumns.Create(TCustomTableColumn);
  1500. end;
  1501. function TCustomTableWidget.DefaultTableOptions: TTableOptions;
  1502. begin
  1503. Result:=[toHeader,toBody,toFooter,toHeaderRow]
  1504. end;
  1505. procedure TCustomTableWidget.CreateDefaultColumns;
  1506. begin
  1507. // Do nothing
  1508. end;
  1509. constructor TCustomTableWidget.Create(aOwner: TComponent);
  1510. begin
  1511. inherited Create(aOwner);
  1512. FTableOptions:=DefaultTableOptions;
  1513. FColumns:=CreateColumns;
  1514. end;
  1515. destructor TCustomTableWidget.Destroy;
  1516. begin
  1517. FreeAndNil(FColumns);
  1518. inherited Destroy;
  1519. end;
  1520. procedure TCustomTableWidget.BeginUpdate;
  1521. begin
  1522. Inc(FUpDateCount);
  1523. end;
  1524. procedure TCustomTableWidget.EndUpdate;
  1525. begin
  1526. if (FUpdateCount>0) then
  1527. Dec(FUpDateCount);
  1528. if (FUpdateCount=0) and IsRendered then
  1529. Refresh;
  1530. end;
  1531. procedure TCustomTableWidget.RefreshBody;
  1532. begin
  1533. if Not Assigned(Element) then
  1534. Refresh
  1535. else
  1536. begin
  1537. Element.Innerhtml:='';
  1538. RenderData(Element);
  1539. end;
  1540. end;
  1541. { TCustomTableColumn }
  1542. procedure TCustomTableColumn.SetAlignment(AValue: TAlignment);
  1543. begin
  1544. if FAlignment=AValue then Exit;
  1545. FAlignment:=AValue;
  1546. end;
  1547. function TCustomTableColumn.GetCaption: String;
  1548. begin
  1549. Result:=FCaption;
  1550. end;
  1551. procedure TCustomTableColumn.SetCaption(AValue: String);
  1552. begin
  1553. if FCaption=AValue then Exit;
  1554. FCaption:=AValue;
  1555. end;
  1556. procedure TCustomTableColumn.SetClassNames(AValue: String);
  1557. begin
  1558. if FClassNames=AValue then Exit;
  1559. FClassNames:=AValue;
  1560. end;
  1561. function TCustomTableColumn.GetDisplayName: string;
  1562. begin
  1563. Result:=Caption;
  1564. end;
  1565. procedure TCustomTableColumn.Assign(Source: TPersistent);
  1566. Var
  1567. C : TCustomTableColumn;
  1568. begin
  1569. if Source is TCustomTableColumn then
  1570. begin
  1571. C:=Source as TCustomTableColumn;
  1572. FCaption:=C.FCaption;
  1573. FClassNames:=C.FClassNames;
  1574. FAlignment:=C.Alignment;
  1575. end
  1576. else
  1577. inherited Assign(Source);
  1578. end;
  1579. { TCustomTableColumns }
  1580. function TCustomTableColumns.GetCustomColumn(Index : Integer): TCustomTableColumn;
  1581. begin
  1582. Result:=TCustomTableColumn(Items[Index]);
  1583. end;
  1584. procedure TCustomTableColumns.SetCustomColumn(Index : Integer; AValue: TCustomTableColumn);
  1585. begin
  1586. Items[Index]:=aValue;
  1587. end;
  1588. function TCustomTableColumns.Add(aCaption: String): TCustomTableColumn;
  1589. begin
  1590. Result:=add as TCustomTableColumn;
  1591. Result.Caption:=aCaption;
  1592. end;
  1593. { TTableRowEnumerator }
  1594. constructor TTableRowEnumerator.Create(ATable: TCustomTableWidget);
  1595. begin
  1596. FTable:=aTable;
  1597. FCurrent:=-1;
  1598. end;
  1599. function TTableRowEnumerator.MoveNext: Boolean;
  1600. begin
  1601. Inc(FCurrent);
  1602. Result:=True;
  1603. end;
  1604. { TCustomTextWidget }
  1605. procedure TCustomTextWidget.SetEnvelopeTag(AValue: TTextTag);
  1606. begin
  1607. // Writeln('Setting text tag : ',aValue);
  1608. if FEnvelopeTag=AValue then Exit;
  1609. FEnvelopeTag:=AValue;
  1610. if (FEnvelopeTag=ttCustom) and (FCustomTag='') then
  1611. FCustomTag:='div';
  1612. if IsRendered then
  1613. Refresh;
  1614. end;
  1615. procedure TCustomTextWidget.SetCustomTag(AValue: String);
  1616. begin
  1617. if FCustomTag=AValue then Exit;
  1618. FCustomTag:=AValue;
  1619. if (FCustomTag<>'') then
  1620. FEnvelopeTag:=ttCustom;
  1621. if IsRendered then
  1622. Refresh;
  1623. end;
  1624. procedure TCustomTextWidget.SetTextMode(AValue: TTextMode);
  1625. begin
  1626. if FTextMode=AValue then Exit;
  1627. FTextMode:=AValue;
  1628. if IsRendered then
  1629. ApplyText(Element);
  1630. end;
  1631. procedure TCustomTextWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1632. begin
  1633. // Writeln('ApplyWidgetSettings: ',aElement.tagName);
  1634. inherited ApplyWidgetSettings(aElement);
  1635. ApplyText(aElement);
  1636. end;
  1637. procedure TCustomTextWidget.ApplyText(aElement: TJSHTMLElement);
  1638. begin
  1639. if FTextMode=tmText then
  1640. aElement.innerText:=GetText
  1641. else
  1642. aElement.innerHTML:=GetText;
  1643. end;
  1644. function TCustomTextWidget.HTMLTag: String;
  1645. begin
  1646. Result:=TextTagNames[FEnvelopeTag];
  1647. if Result='' then
  1648. Result:='div';
  1649. // Writeln('Getting element tag: ',Result);
  1650. end;
  1651. { TTextLinesWidget }
  1652. procedure TTextLinesWidget.SetLines(AValue: TStrings);
  1653. begin
  1654. if FLines=AValue then Exit;
  1655. FLines.Assign(AValue);
  1656. end;
  1657. procedure TTextLinesWidget.SetForceLineBreaks(AValue: Boolean);
  1658. begin
  1659. if FForceLineBreaks=AValue then Exit;
  1660. FForceLineBreaks:=AValue;
  1661. if IsRendered then
  1662. ApplyText(Element);
  1663. end;
  1664. procedure TTextLinesWidget.DoLinesChanged(Sender: TObject);
  1665. begin
  1666. if IsRendered then
  1667. ApplyText(Element);
  1668. end;
  1669. function TTextLinesWidget.GetText: String;
  1670. Var
  1671. I : integer;
  1672. begin
  1673. if (FTextMode=tmHTML) and ForceLineBreaks then
  1674. begin
  1675. Result:='';
  1676. For I:=0 to FLines.Count-1 do
  1677. Result:=Result+flines[i]+'<br/>';
  1678. end
  1679. else
  1680. Result:=FLines.Text;
  1681. end;
  1682. procedure TTextLinesWidget.ApplyText(aElement: TJSHTMLElement);
  1683. Var
  1684. I : integer;
  1685. begin
  1686. if (TextMode=tmHTML) or (Not ForceLineBreaks) then
  1687. inherited ApplyText(aElement)
  1688. else
  1689. begin
  1690. For I:=0 to FLines.Count-1 do
  1691. begin
  1692. aElement.AppendChild(Document.createTextNode(FLines[i]));
  1693. aElement.AppendChild(CreateElement('br',''));
  1694. end;
  1695. end;
  1696. end;
  1697. constructor TTextLinesWidget.Create(aOwner: TComponent);
  1698. begin
  1699. inherited Create(aOwner);
  1700. FLines:=TstringList.Create;
  1701. TstringList(FLines).OnChange:=@DoLinesChanged;
  1702. end;
  1703. destructor TTextLinesWidget.Destroy;
  1704. begin
  1705. FLines:=TstringList.Create;
  1706. inherited Destroy;
  1707. end;
  1708. { TTextWidget }
  1709. procedure TTextWidget.SetText(AValue: String);
  1710. begin
  1711. if FText=AValue then Exit;
  1712. FText:=AValue;
  1713. if IsRendered then
  1714. ApplyText(Element);
  1715. end;
  1716. function TTextWidget.GetText: String;
  1717. begin
  1718. Result:=FText;
  1719. end;
  1720. { TLabelWidget }
  1721. procedure TLabelWidget.ApplyLabelFor(aLabelElement : TJSHTMLLabelElement);
  1722. begin
  1723. if Assigned(FlabelFor) then
  1724. begin
  1725. FlabelFor.EnsureElement;
  1726. aLabelElement.for_:=FlabelFor.ElementID;
  1727. end
  1728. else
  1729. aLabelElement.for_:='';
  1730. end;
  1731. procedure TLabelWidget.SetLabelFor(AValue: TWebWidget);
  1732. begin
  1733. if (FLabelFor=AValue) then Exit;
  1734. if Assigned(FLabelFor) then
  1735. FLabelFor.RemoveFreeNotification(Self);
  1736. FLabelFor:=AValue;
  1737. if Assigned(FLabelFor) then
  1738. FLabelFor.FreeNotification(Self);
  1739. If IsRendered then
  1740. ApplyLabelFor(LabelElement);
  1741. end;
  1742. function TLabelWidget.GetText: String;
  1743. begin
  1744. if IsElementDirty then
  1745. FText:=Element.InnerText;
  1746. Result:=FText;
  1747. end;
  1748. function TLabelWidget.GetLabelEl: TJSHTMLLabelElement;
  1749. begin
  1750. Result:=TJSHTMLLabelElement(Element);
  1751. end;
  1752. procedure TLabelWidget.SetText(AValue: String);
  1753. begin
  1754. If Text=aValue then exit;
  1755. Ftext:=aValue;
  1756. If IsRendered then
  1757. Element.innerText:=aValue;
  1758. end;
  1759. procedure TLabelWidget.Notification(AComponent: TComponent; Operation: TOperation);
  1760. begin
  1761. inherited Notification(AComponent, Operation);
  1762. if (Operation=opRemove) and (aComponent=FLabelFor) then
  1763. FLabelFor:=Nil;
  1764. end;
  1765. procedure TLabelWidget.SetName(const NewName: TComponentName);
  1766. Var
  1767. Old : String;
  1768. begin
  1769. Old:=Name;
  1770. inherited SetName(NewName);
  1771. if (csDesigning in ComponentState) then
  1772. if Old=Text then
  1773. Text:=Old;
  1774. end;
  1775. procedure TLabelWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1776. var
  1777. lbl : TJSHTMLLabelElement absolute aElement;
  1778. begin
  1779. inherited ApplyWidgetSettings(aElement);
  1780. lbl.InnerText:=Text;
  1781. ApplyLabelFor(Lbl);
  1782. end;
  1783. function TLabelWidget.HTMLTag: String;
  1784. begin
  1785. Result:='label';
  1786. end;
  1787. { TSelectWidget }
  1788. function TCustomSelectWidget.GetSelectedIndex: Integer;
  1789. begin
  1790. if IsRendered then
  1791. FSelectedIndex:=SelectElement.selectedIndex;
  1792. Result:=FSelectedIndex
  1793. end;
  1794. function TCustomSelectWidget.GetMultiple: Boolean;
  1795. begin
  1796. if IsElementDirty then
  1797. FMultiple:=SelectElement.multiple;
  1798. Result:=FMultiple;
  1799. end;
  1800. function TCustomSelectWidget.GetItemCount: Integer;
  1801. begin
  1802. Result:=Length(Options);
  1803. end;
  1804. function TCustomSelectWidget.GetSelected(Index : Integer): Boolean;
  1805. begin
  1806. if (Index<0) or (Index>=Length(Foptions)) then
  1807. Raise EWidgets.CreateFmt(SErrInvalidIndex,[Index,Length(Foptions)-1]);
  1808. Result:=FOptions[Index].Selected
  1809. end;
  1810. function TCustomSelectWidget.GetSelect: TJSHTMLSelectElement;
  1811. begin
  1812. Result:=TJSHTMLSelectElement(Element);
  1813. end;
  1814. function TCustomSelectWidget.GetSelectionCount: Integer;
  1815. begin
  1816. Result:=SelectElement.selectedOptions.length;
  1817. end;
  1818. function TCustomSelectWidget.GetSelectionItem(aIndex : Integer): String;
  1819. begin
  1820. if (aIndex<0) or (aindex>=GetSelectionCount) then
  1821. Raise EWidgets.CreateFmt(SErrInvalidIndex,[aIndex,GetSelectionCount-1]);
  1822. Result:=TJSHTMLOptionElement(SelectElement.selectedOptions.item(aIndex)).innerText;
  1823. end;
  1824. function TCustomSelectWidget.GetSelectionValue(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)).value;
  1829. end;
  1830. function TCustomSelectWidget.GetSize: Integer;
  1831. begin
  1832. if IsElementDirty then
  1833. FSize:=SelectElement.Size;
  1834. Result:=FSize;
  1835. end;
  1836. procedure TCustomSelectWidget.SetMultiple(AValue: Boolean);
  1837. begin
  1838. If (AValue=Multiple) then exit;
  1839. FMultiple:=aValue;
  1840. If IsRendered then
  1841. SelectElement.multiple:=FMultiple;
  1842. end;
  1843. procedure TCustomSelectWidget.SetSelected(Index : Integer; AValue: Boolean);
  1844. begin
  1845. if (Index<0) or (Index>=Length(Foptions)) then
  1846. Raise EWidgets.CreateFmt(SErrInvalidIndex,[Index,Length(Foptions)-1]);
  1847. FOptions[Index].Selected:=aValue;
  1848. end;
  1849. procedure TCustomSelectWidget.SetSelectedIndex(AValue: Integer);
  1850. begin
  1851. if (SelectedIndex=aValue) then
  1852. Exit;
  1853. FSelectedIndex:=aValue;
  1854. if IsRendered then
  1855. SelectElement.SelectedIndex:=FSelectedIndex;
  1856. if Assigned(OnChange) then
  1857. OnChange(Self,Nil);
  1858. end;
  1859. procedure TCustomSelectWidget.SetSize(AValue: Integer);
  1860. begin
  1861. If (AValue=Size) then exit;
  1862. FSize:=aValue;
  1863. If IsRendered then
  1864. SelectElement.Size:=FSize;
  1865. end;
  1866. procedure TCustomSelectWidget.BuildOptions(aSelect: TJSHTMLSelectElement);
  1867. Var
  1868. O : TJSHTMLOptionElement;
  1869. Idx : Integer;
  1870. enum : TSelectOptionEnumerator;
  1871. begin
  1872. // Clear
  1873. SetLength(FOptions,0);
  1874. aSelect.InnerHTML:='';
  1875. // Rebuild
  1876. Idx:=0;
  1877. enum:=CreateOptionEnumerator;
  1878. While enum.MoveNext do
  1879. begin
  1880. O:=TJSHTMLOptionElement(CreateElement('option',''));
  1881. O.innerText:=enum.OptionText;
  1882. if enum.HasValue then
  1883. O.value:=enum.Value;
  1884. if Idx=FSelectedIndex then
  1885. O.selected:=True;
  1886. aSelect.AppendChild(O);
  1887. Inc(Idx);
  1888. end;
  1889. SetLength(Foptions,Idx);
  1890. Dec(idx);
  1891. While Idx>=0 do
  1892. begin
  1893. FOptions[Idx]:=TJSHTMLOptionElement(aSelect.Children[Idx]);
  1894. dec(Idx);
  1895. end;
  1896. end;
  1897. constructor TCustomSelectWidget.Create(aOWner: TComponent);
  1898. begin
  1899. inherited Create(aOWner);
  1900. FSelectedIndex:=-1;
  1901. end;
  1902. procedure TCustomSelectWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  1903. Var
  1904. el : TJSHTmlSelectElement absolute aElement;
  1905. begin
  1906. inherited ApplyWidgetSettings(aElement);
  1907. el.multiple:=Self.Multiple;
  1908. el.Size:=Self.Size;
  1909. BuildOptions(el);
  1910. // We need to force this.
  1911. if SelectedIndex=-1 then
  1912. el.selectedIndex:=-1;
  1913. end;
  1914. function TCustomSelectWidget.HTMLTag: String;
  1915. begin
  1916. Result:='select';
  1917. end;
  1918. { TSelectWidget }
  1919. function TSelectWidget.GetItems: TStrings;
  1920. begin
  1921. Result:=FItems;
  1922. end;
  1923. function TSelectWidget.GetValues: TStrings;
  1924. begin
  1925. Result:=FValues;
  1926. end;
  1927. procedure TSelectWidget.OptionsChanged(Sender: TObject);
  1928. begin
  1929. if IsRendered then
  1930. BuildOptions(SelectElement);
  1931. end;
  1932. procedure TSelectWidget.setItems(AValue: TStrings);
  1933. begin
  1934. If (AValue=FItems) then exit;
  1935. FItems.Assign(aValue);
  1936. end;
  1937. procedure TSelectWidget.setValues(AValue: TStrings);
  1938. begin
  1939. If (AValue=FValues) then exit;
  1940. FValues.Assign(aValue);
  1941. end;
  1942. function TSelectWidget.CreateOptionEnumerator: TSelectOptionEnumerator;
  1943. begin
  1944. Result:=TStringsSelectOptionEnumerator.Create(Self);
  1945. end;
  1946. constructor TSelectWidget.Create(aOWner: TComponent);
  1947. begin
  1948. inherited Create(aOWner);
  1949. FItems:=TStringList.Create;
  1950. TStringList(FItems).OnChange:=@OptionsChanged;
  1951. FValues:=TStringList.Create;
  1952. TStringList(FValues).OnChange:=@OptionsChanged;
  1953. end;
  1954. destructor TSelectWidget.Destroy;
  1955. begin
  1956. FreeAndNil(FItems);
  1957. FreeAndNil(FValues);
  1958. inherited Destroy;
  1959. end;
  1960. { TImageWidget }
  1961. function TImageWidget.GetHeight: Integer;
  1962. begin
  1963. if IsElementDirty then
  1964. FHeight:=ImgElement.Height;
  1965. Result:=Fheight;
  1966. end;
  1967. function TImageWidget.GetImg: TJSHTMLImageElement;
  1968. begin
  1969. Result:=TJSHTMLImageElement(Element);
  1970. end;
  1971. function TImageWidget.GetSrc: String;
  1972. begin
  1973. if IsElementDirty then
  1974. FSrc:=ImgElement.Src;
  1975. Result:=FSrc;
  1976. end;
  1977. function TImageWidget.GetWidth: Integer;
  1978. begin
  1979. if IsElementDirty then
  1980. FWidth:=ImgElement.Width;
  1981. Result:=FWidth;
  1982. end;
  1983. procedure TImageWidget.SetHeight(AValue: Integer);
  1984. begin
  1985. if AValue=Height then exit;
  1986. FHeight:=AValue;
  1987. If isrendered then
  1988. ImgElement.Height:=aValue;
  1989. end;
  1990. procedure TImageWidget.SetSrc(AValue: String);
  1991. begin
  1992. if AValue=Src then exit;
  1993. FSrc:=AValue;
  1994. If isrendered then
  1995. ImgElement.Src:=FSrc;
  1996. end;
  1997. procedure TImageWidget.SetWidth(AValue: Integer);
  1998. begin
  1999. if AValue=Width then exit;
  2000. FWidth:=AValue;
  2001. If isrendered then
  2002. ImgElement.Width:=aValue;
  2003. end;
  2004. procedure TImageWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2005. var
  2006. img : TJSHTMLImageElement absolute aElement;
  2007. begin
  2008. inherited ApplyWidgetSettings(aElement);
  2009. Img.Src:=FSrc;
  2010. Img.Height:=FHeight;
  2011. Img.Width:=FWidth;
  2012. end;
  2013. function TImageWidget.HTMLTag: String;
  2014. begin
  2015. Result:='img';
  2016. end;
  2017. { TTextAreaWidget }
  2018. procedure TTextAreaWidget.SetLines(AValue: TStrings);
  2019. begin
  2020. if FLines=AValue then Exit;
  2021. FLines.Assign(AValue);
  2022. end;
  2023. procedure TTextAreaWidget.SetMaxLength(AValue: Cardinal);
  2024. begin
  2025. if FMaxLength=AValue then Exit;
  2026. FMaxLength:=AValue;
  2027. if IsRendered then
  2028. TextArea.maxLength:=aValue;
  2029. end;
  2030. procedure TTextAreaWidget.SetReadonly(AValue: Boolean);
  2031. begin
  2032. If aValue=ReadOnly then exit;
  2033. FReadOnly:=aValue;
  2034. if IsRendered then
  2035. TextArea.Readonly:=FReadOnly;
  2036. end;
  2037. procedure TTextAreaWidget.SetRequired(AValue: Boolean);
  2038. begin
  2039. If aValue=Required then exit;
  2040. FRequired:=aValue;
  2041. if IsRendered then
  2042. TextArea.Required:=FRequired;
  2043. end;
  2044. function TTextAreaWidget.GetColumns: Cardinal;
  2045. begin
  2046. if IsElementDirty then
  2047. FColumns:=TextArea.Cols;
  2048. Result:=FColumns;
  2049. end;
  2050. procedure TTextAreaWidget.DoLineChanges(Sender: TObject);
  2051. begin
  2052. if isRendered and not FIgnoreChanges then
  2053. ApplyLines(TextArea);
  2054. end;
  2055. function TTextAreaWidget.GetLines: TStrings;
  2056. begin
  2057. // We may want to change this to something more efficient. Maybe handle onchange
  2058. // Note that if yo
  2059. if IsElementDirty then
  2060. begin
  2061. FIgnoreChanges:=True;
  2062. try
  2063. LinesFromHTML(Element.InnerHTml);
  2064. finally
  2065. FIgnoreChanges:=False;
  2066. end;
  2067. end;
  2068. Result:=FLines;
  2069. end;
  2070. function TTextAreaWidget.GetReadOnly: Boolean;
  2071. begin
  2072. if IsElementDirty then
  2073. FReadonly:=TextArea.readOnly;
  2074. Result:=FReadonly;
  2075. end;
  2076. function TTextAreaWidget.GetRequired: Boolean;
  2077. begin
  2078. if IsElementDirty then
  2079. FRequired:=TextArea.Required;
  2080. Result:=FRequired;
  2081. end;
  2082. function TTextAreaWidget.GetRows: Cardinal;
  2083. begin
  2084. if IsElementDirty then
  2085. FRows:=TextArea.Rows;
  2086. Result:=FRows;
  2087. end;
  2088. function TTextAreaWidget.GetText: String;
  2089. begin
  2090. if IsElementDirty then
  2091. Result:=Element.InnerHTML
  2092. else
  2093. Result:=FLines.Text;
  2094. end;
  2095. function TTextAreaWidget.GetValueName: string;
  2096. begin
  2097. if IsElementDirty then
  2098. FValueName:=Element.Name;
  2099. Result:=FValueName;
  2100. end;
  2101. procedure TTextAreaWidget.SetColumns(AValue: Cardinal);
  2102. begin
  2103. if AValue=FColumns then exit;
  2104. FColumns:=aValue;
  2105. if isRendered then
  2106. TextArea.cols:=aValue;
  2107. end;
  2108. procedure TTextAreaWidget.SetRows(AValue: Cardinal);
  2109. begin
  2110. if AValue=FRows then exit;
  2111. FRows:=aValue;
  2112. if isRendered then
  2113. TextArea.Rows:=aValue;
  2114. end;
  2115. procedure TTextAreaWidget.SetText(AValue: String);
  2116. begin
  2117. if isRendered then
  2118. element.InnerText:=aValue
  2119. else
  2120. LinesFromHTML(aValue);
  2121. end;
  2122. procedure TTextAreaWidget.SetValueName(AValue: string);
  2123. begin
  2124. if aValue=FValueName then exit;
  2125. FValueName:=aValue;
  2126. if IsRendered then
  2127. TextArea.Name:=aValue;
  2128. end;
  2129. procedure TTextAreaWidget.SetName(const NewName: TComponentName);
  2130. var
  2131. Old : String;
  2132. begin
  2133. Old:=Name;
  2134. inherited SetName(NewName);
  2135. if csDesigning in ComponentState then
  2136. begin
  2137. if (FLines.Count=0) then
  2138. FLines.Add(Name)
  2139. else if (FLines.Count=1) and (FLines[0]=Old) then
  2140. FLines[0]:=Name;
  2141. end;
  2142. end;
  2143. procedure TTextAreaWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2144. var
  2145. area : TJSHTMLTextAreaElement absolute aElement;
  2146. begin
  2147. inherited ApplyWidgetSettings(aElement);
  2148. if FMaxLength>0 then
  2149. area.maxlength:=FMaxLength;
  2150. if FColumns>0 then
  2151. area.cols:=FColumns;
  2152. if FRows>0 then
  2153. area.Rows:=FRows;
  2154. if FLines.Count>0 then
  2155. ApplyLines(area);
  2156. if FValueName<>'' then
  2157. area.Name:=FValueName;
  2158. area.Readonly:=FReadOnly;
  2159. area.Required:=FRequired;
  2160. ApplyWrap(area);
  2161. end;
  2162. constructor TTextAreaWidget.Create(aOwner: TComponent);
  2163. begin
  2164. inherited Create(aOwner);
  2165. FLines:=TStringList.Create;
  2166. TStringList(FLines).OnChange:=@DoLineChanges;
  2167. FColumns:=50;
  2168. FRows:=10;
  2169. end;
  2170. destructor TTextAreaWidget.Destroy;
  2171. begin
  2172. FreeAndNil(Flines);
  2173. inherited;
  2174. end;
  2175. class function TTextAreaWidget.AllowChildren: Boolean;
  2176. begin
  2177. Result:=False;
  2178. end;
  2179. function TTextAreaWidget.GetTextArea: TJSHTMLTextAreaElement;
  2180. begin
  2181. Result:=TJSHTMLTextAreaElement(Element);
  2182. end;
  2183. procedure TTextAreaWidget.ApplyWrap(aElement :TJSHTMLTextAreaElement);
  2184. Const
  2185. Wraps : Array[TTextAreaWrap] of string = ('soft','hard','off');
  2186. begin
  2187. aElement.wrap:=Wraps[FWrap];
  2188. end;
  2189. procedure TTextAreaWidget.ApplyLines(aElement: TJSHTMLTextAreaElement);
  2190. begin
  2191. aElement.innerHTML:=FLines.Text;
  2192. end;
  2193. procedure TTextAreaWidget.LinesFromHTML(aHTML: String);
  2194. begin
  2195. FLines.Text:= StringReplace(aHTML,'<br>',sLineBreak,[rfIgnoreCase,rfReplaceAll]);
  2196. end;
  2197. procedure TTextAreaWidget.SetWrap(AValue: TTextAreaWrap);
  2198. begin
  2199. if FWrap=AValue then Exit;
  2200. FWrap:=AValue;
  2201. if IsRendered then
  2202. ApplyWrap(TextArea)
  2203. end;
  2204. function TTextAreaWidget.HTMLTag: String;
  2205. begin
  2206. result:='textarea';
  2207. end;
  2208. { TCheckboxInputWidget }
  2209. function TCheckboxInputWidget.InputType: String;
  2210. begin
  2211. Result:='checkbox';
  2212. end;
  2213. { TRadioInputWidget }
  2214. function TRadioInputWidget.InputType: String;
  2215. begin
  2216. Result:='radio';
  2217. end;
  2218. { THiddenInputWidget }
  2219. class function THiddenInputWidget.AllowChildren: Boolean;
  2220. begin
  2221. Result:=False;
  2222. end;
  2223. function THiddenInputWidget.InputType: String;
  2224. begin
  2225. Result:='hidden';
  2226. end;
  2227. { TFileInputWidget }
  2228. procedure TFileInputWidget.SetMultiple(AValue: Boolean);
  2229. begin
  2230. if FMultiple=AValue then Exit;
  2231. FMultiple:=AValue;
  2232. if Isrendered then
  2233. InputElement.multiple:=FMultiple;
  2234. end;
  2235. function TFileInputWidget.GetMultiple: Boolean;
  2236. begin
  2237. if IsElementDirty then
  2238. FMultiple:=InputElement.multiple;
  2239. Result:=FMultiple;
  2240. end;
  2241. function TFileInputWidget.GetFileName(aIndex : Integer): String;
  2242. begin
  2243. Result:=InputElement.files.Files[aIndex].name;
  2244. end;
  2245. function TFileInputWidget.GetFileSize(aIndex : Integer): NativeInt;
  2246. begin
  2247. Result:=InputElement.files.Files[aIndex].Size;
  2248. end;
  2249. function TFileInputWidget.GetFileType(aIndex : Integer): String;
  2250. begin
  2251. Result:=InputElement.files.Files[aIndex]._Type;
  2252. end;
  2253. function TFileInputWidget.GetFileCount: Integer;
  2254. begin
  2255. Result:=InputElement.files.Length;
  2256. end;
  2257. function TFileInputWidget.GetFileDate(aIndex : Integer): TDateTime;
  2258. begin
  2259. Result:=JSDateToDateTime(InputElement.files.Files[aIndex].lastModifiedDate);
  2260. end;
  2261. function TFileInputWidget.GetFileInfo(aIndex : Integer): TFileInfo;
  2262. Var
  2263. f : TJSHTMLFile;
  2264. begin
  2265. F:=InputElement.files.Files[aIndex];
  2266. Result.Name:=F.name;
  2267. Result.Size:=F.size;
  2268. Result.FileType:=F._type;
  2269. Result.TimeStamp:= JSDateToDateTime(F.lastModifiedDate);
  2270. end;
  2271. procedure TFileInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2272. Var
  2273. Old : String;
  2274. begin
  2275. Old:=FValue;
  2276. FValue:='';
  2277. try
  2278. inherited ApplyWidgetSettings(aElement);
  2279. TJSHTMLInputElement(aElement).multiple:=FMultiple;
  2280. finally
  2281. FValue:=Old;
  2282. end;
  2283. end;
  2284. class function TFileInputWidget.AllowChildren: Boolean;
  2285. begin
  2286. Result:=False;
  2287. end;
  2288. function TFileInputWidget.InputType: String;
  2289. begin
  2290. Result:='file';
  2291. end;
  2292. { TDateInputWidget }
  2293. function TDateInputWidget.GetDate: TDateTime;
  2294. var
  2295. aDate : TDateTime;
  2296. begin
  2297. if IsElementDirty then
  2298. begin
  2299. aDate:=ScanDateTime('yyyy-mm-dd',Value);
  2300. if aDate<>0 then
  2301. FDate:=aDate;
  2302. end;
  2303. Result:=FDate;
  2304. end;
  2305. procedure TDateInputWidget.SetDate(AValue: TDateTime);
  2306. begin
  2307. FDate:=aValue;
  2308. Value:=FormatDateTime('yyyy-mm-dd',FDate);
  2309. end;
  2310. function TDateInputWidget.InputType: String;
  2311. begin
  2312. Result:='date';
  2313. end;
  2314. class function TDateInputWidget.AllowChildren: Boolean;
  2315. begin
  2316. Result:=False;
  2317. end;
  2318. { TCheckableInputWidget }
  2319. procedure TCheckableInputWidget.SetChecked(AValue: Boolean);
  2320. begin
  2321. // Get actual value
  2322. if Checked=AValue then Exit;
  2323. if isRendered then
  2324. InputElement.checked:=aValue;
  2325. FChecked:=AValue;
  2326. end;
  2327. procedure TCheckableInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2328. begin
  2329. inherited ApplyWidgetSettings(aElement);
  2330. TJSHTMLInputElement(aElement).Checked:=FChecked;
  2331. end;
  2332. function TCheckableInputWidget.GetChecked: Boolean;
  2333. begin
  2334. if IsElementDirty then
  2335. FChecked:=InputElement.Checked;
  2336. Result:=FChecked;
  2337. end;
  2338. { TButtonInputWidget }
  2339. procedure TButtonInputWidget.SetButtonType(AValue: TInputButtonType);
  2340. begin
  2341. if FButtonType=AValue then Exit;
  2342. FButtonType:=AValue;
  2343. if IsRendered then
  2344. Refresh;
  2345. end;
  2346. procedure TButtonInputWidget.SetSrc(AValue: String);
  2347. begin
  2348. if FSrc=AValue then Exit;
  2349. FSrc:=AValue;
  2350. if IsRendered and (ButtonType=ibtImage) then
  2351. Element.setAttribute('src',FSrc);
  2352. end;
  2353. procedure TButtonInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2354. begin
  2355. inherited ApplyWidgetSettings(aElement);
  2356. if ButtonType=ibtImage then
  2357. aElement.setAttribute('src',FSrc);
  2358. end;
  2359. function TButtonInputWidget.InputType: String;
  2360. Const
  2361. Types : Array[TInputButtonType] of string = ('submit','reset','image');
  2362. begin
  2363. Result:=Types[FButtonType]
  2364. end;
  2365. class function TButtonInputWidget.AllowChildren: Boolean;
  2366. begin
  2367. Result:=False;
  2368. end;
  2369. { TTextInputWidget }
  2370. function TTextInputWidget.GetAsNumber: NativeInt;
  2371. begin
  2372. Result:=StrToIntDef(Value,0);
  2373. end;
  2374. function TTextInputWidget.GetMaxLength: NativeInt;
  2375. begin
  2376. if IsElementDirty then
  2377. FMaxLength:=InputElement.maxLength;
  2378. Result:=FMaxLength;
  2379. end;
  2380. function TTextInputWidget.GetMinLength: NativeInt;
  2381. begin
  2382. if IsElementDirty then
  2383. FMinLength:=InputElement.minLength;
  2384. Result:=FMinLength;
  2385. end;
  2386. function TTextInputWidget.GetTextType: TInputTextType;
  2387. begin
  2388. Result:=FTextType;
  2389. end;
  2390. procedure TTextInputWidget.SetAsNumber(AValue: NativeInt);
  2391. begin
  2392. Value:=IntToStr(aValue);
  2393. end;
  2394. procedure TTextInputWidget.SetMaxLength(AValue: NativeInt);
  2395. begin
  2396. if (aValue=FMaxLength) then exit;
  2397. FMaxLength:=aValue;
  2398. if IsRendered then
  2399. InputElement.maxLength:=FMaxLength;
  2400. end;
  2401. procedure TTextInputWidget.SetMinLength(AValue: NativeInt);
  2402. begin
  2403. if (aValue=FMinLength) then exit;
  2404. FMinLength:=aValue;
  2405. if IsRendered then
  2406. InputElement.minLength:=FMinLength;
  2407. end;
  2408. procedure TTextInputWidget.SetTextType(AValue: TInputTextType);
  2409. begin
  2410. if aValue=FTextType then exit;
  2411. FTextType:=aValue;
  2412. if IsRendered then
  2413. Refresh;
  2414. end;
  2415. procedure TTextInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2416. var
  2417. inp : TJSHTMLInputElement absolute aElement;
  2418. begin
  2419. inherited ApplyWidgetSettings(aElement);
  2420. if FMaxLength<>0 then
  2421. inp.maxLength:=FMaxLength;
  2422. if FMinLength<>0 then
  2423. inp.minLength:=FMinLength;
  2424. end;
  2425. class function TTextInputWidget.AllowChildren: Boolean;
  2426. begin
  2427. Result:=False;
  2428. end;
  2429. function TTextInputWidget.InputType: String;
  2430. Const
  2431. Types : Array[TInputTextType] of string =
  2432. ('text','password','number','email','search','tel','url','color');
  2433. begin
  2434. Result:=Types[FTextType];
  2435. end;
  2436. { TWebPage }
  2437. constructor TWebPage.Create(AOwner: TComponent);
  2438. begin
  2439. inherited Create(AOwner);
  2440. Classes:='WebPage';
  2441. end;
  2442. class function TWebPage.DefaultParentElement: TJSHTMLElement;
  2443. begin
  2444. Result:=TViewport.Instance.Element;
  2445. end;
  2446. class function TWebPage.DefaultParent: TCustomWebWidget;
  2447. begin
  2448. Result:=TViewport.Instance;
  2449. end;
  2450. procedure TWebPage.DoUnRender(aParent: TJSHTMLElement);
  2451. begin
  2452. inherited DoUnRender(aParent);
  2453. end;
  2454. function TWebPage.HTMLTag: String;
  2455. begin
  2456. Result:='div';
  2457. end;
  2458. { TViewPort }
  2459. function TViewPort.HTMLTag: String;
  2460. begin
  2461. Result:='body';
  2462. end;
  2463. class function TViewPort.FixedParent: TJSHTMLElement;
  2464. begin
  2465. Result:=TJSHTMLElement(Document.documentElement);
  2466. end;
  2467. class function TViewPort.FixedElement: TJSHTMLElement;
  2468. begin
  2469. Result:=TJSHTMLElement(Document.Body);
  2470. end;
  2471. function TViewPort.DoRenderHTML(aParent, aElement: TJSHTMLElement): TJSHTMLElement;
  2472. begin
  2473. Result:=FixedElement;
  2474. end;
  2475. constructor TViewPort.Create(aOwner: TComponent);
  2476. begin
  2477. inherited Create(aOwner);
  2478. EnsureElement;
  2479. end;
  2480. class function TViewPort.Instance: TViewPort;
  2481. begin
  2482. if Finstance=Nil then
  2483. FInstance:=TViewPort.Create(Nil);
  2484. Result:=FInstance;
  2485. end;
  2486. { TButtonWidget }
  2487. { TButtonWidget }
  2488. procedure TButtonWidget.SetText(AValue: String);
  2489. begin
  2490. if FText=AValue then Exit;
  2491. FText:=AValue;
  2492. if IsRendered then
  2493. ApplyText(Element);
  2494. end;
  2495. procedure TButtonWidget.SetTextMode(AValue: TTextMode);
  2496. begin
  2497. if FTextMode=AValue then Exit;
  2498. FTextMode:=AValue;
  2499. if IsRendered then
  2500. ApplyText(Element)
  2501. end;
  2502. procedure TButtonWidget.SetName(const NewName: TComponentName);
  2503. Var
  2504. Old : String;
  2505. begin
  2506. Old:=Name;
  2507. inherited SetName(NewName);
  2508. if (FText=Old) and (csDesigning in ComponentState) then
  2509. FText:=NewName;
  2510. end;
  2511. function TButtonWidget.HTMLTag: String;
  2512. begin
  2513. Result:='button';
  2514. end;
  2515. procedure TButtonWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2516. begin
  2517. Inherited;
  2518. ApplyText(aElement);
  2519. end;
  2520. Procedure TButtonWidget.ApplyText(aElement : TJSHTMLElement);
  2521. begin
  2522. if FTextMode=tmText then
  2523. aElement.InnerText:=FText
  2524. else
  2525. aElement.InnerHTML:=FText;
  2526. end;
  2527. procedure TButtonWidget.Click;
  2528. begin
  2529. DispatchEvent('click');
  2530. end;
  2531. { TCustomInputWidget }
  2532. function TCustomInputWidget.GetValue: String;
  2533. Var
  2534. Inp : TJSHTMLInputElement;
  2535. begin
  2536. Inp:=InputElement;
  2537. If Assigned(Inp) then
  2538. Result:=Inp.value
  2539. else
  2540. Result:=FValue
  2541. end;
  2542. function TCustomInputWidget.GetText: String;
  2543. Var
  2544. Inp : TJSHTMLElement;
  2545. begin
  2546. Inp:=Element;
  2547. If Assigned(Inp) then
  2548. Result:=Inp.InnerText
  2549. else
  2550. Result:=FText;
  2551. // Writeln('Getting text: ',Result,' inner : ',FText);
  2552. end;
  2553. function TCustomInputWidget.GetReadOnly: Boolean;
  2554. begin
  2555. if IsElementDirty then
  2556. FReadonly:=InputElement.readOnly;
  2557. Result:=FReadonly;
  2558. end;
  2559. function TCustomInputWidget.GetRequired: Boolean;
  2560. begin
  2561. if IsElementDirty then
  2562. FRequired:=InputElement.Required;
  2563. Result:=FRequired;
  2564. end;
  2565. function TCustomInputWidget.GetValueName: String;
  2566. Var
  2567. Inp : TJSHTMLInputElement;
  2568. begin
  2569. Inp:=InputElement;
  2570. If Assigned(Inp) then
  2571. Result:=Inp.Name
  2572. else
  2573. begin
  2574. Result:=FValueName;
  2575. if Result='' then
  2576. Result:=Name;
  2577. end;
  2578. end;
  2579. procedure TCustomInputWidget.SetReadonly(AValue: Boolean);
  2580. begin
  2581. If aValue=ReadOnly then exit;
  2582. FReadOnly:=aValue;
  2583. if IsRendered then
  2584. InputElement.Readonly:=FReadOnly;
  2585. end;
  2586. procedure TCustomInputWidget.SetRequired(AValue: Boolean);
  2587. begin
  2588. If aValue=Required then exit;
  2589. FRequired:=aValue;
  2590. if IsRendered then
  2591. InputElement.Required:=FRequired;
  2592. end;
  2593. procedure TCustomInputWidget.SetText(AValue: String);
  2594. Var
  2595. Inp : TJSHTMLElement;
  2596. begin
  2597. Writeln('Setting text: ',AValue,' previous : ',Text);
  2598. if aValue=Text then exit;
  2599. FText:=aValue;
  2600. Inp:=Element;
  2601. If Assigned(Inp) then
  2602. Inp.innerText:=aValue;
  2603. end;
  2604. procedure TCustomInputWidget.SetValue(AValue: String);
  2605. Var
  2606. Inp : TJSHTMLInputElement;
  2607. begin
  2608. if aValue=Value then exit;
  2609. FValue:=aValue;
  2610. Inp:=InputElement;
  2611. If Assigned(Inp) then
  2612. Inp.value:=aValue;
  2613. end;
  2614. procedure TCustomInputWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2615. var
  2616. Inp : TJSHTMLInputElement absolute aElement;
  2617. begin
  2618. Inherited;
  2619. if (ExternalElement) and (FValue='') then
  2620. FValue:=TJSHTMLInputElement(aElement).value
  2621. else
  2622. begin
  2623. Inp._type:=InputType;
  2624. Inp.name:=FValueName;
  2625. Inp.value:=FValue;
  2626. Inp.Required:=FRequired;
  2627. Inp.ReadOnly:=FReadOnly;
  2628. Writeln('Setting inner text to "',FText,'"');
  2629. Inp.innerHtml:=FText;
  2630. Writeln('Setting inner text is now "',Inp.innerText,'"');
  2631. end;
  2632. end;
  2633. function TCustomInputWidget.HTMLTag: String;
  2634. begin
  2635. Result:='input';
  2636. end;
  2637. function TCustomInputWidget.GetInputElement: TJSHTMLInputElement;
  2638. begin
  2639. Result:=TJSHTMLInputElement(Element);
  2640. end;
  2641. procedure TCustomInputWidget.SetValueName(AValue: String);
  2642. Var
  2643. Inp : TJSHTMLInputElement;
  2644. begin
  2645. if aValue=ValueName then exit;
  2646. FValueName:=aValue;
  2647. Inp:=InputElement;
  2648. If Assigned(Inp) then
  2649. Inp.name:=aValue;
  2650. end;
  2651. procedure TCustomInputWidget.SetName(const NewName: TComponentName);
  2652. Var
  2653. Old : String;
  2654. begin
  2655. Old:=Name;
  2656. inherited SetName(NewName);
  2657. if (Value=Old) then
  2658. Value:=NewName;
  2659. end;
  2660. { TCustomTagWidget }
  2661. procedure TCustomTagWidget.SetElementTag(AValue: THTMLElementTag);
  2662. begin
  2663. if FElementTag=AValue then Exit;
  2664. FElementTag:=AValue;
  2665. if IsRendered then
  2666. Refresh;
  2667. end;
  2668. procedure TCustomTagWidget.SetTextContent(AValue: String);
  2669. begin
  2670. if FTextContent=AValue then Exit;
  2671. FTextContent:=AValue;
  2672. if IsRendered then
  2673. Refresh;
  2674. end;
  2675. procedure TCustomTagWidget.ApplyWidgetSettings(aElement: TJSHTMLElement);
  2676. begin
  2677. inherited ApplyWidgetSettings(aElement);
  2678. if FTextContent<>'' then
  2679. aElement.InnerText:=TextContent;
  2680. end;
  2681. function TCustomTagWidget.HTMLTag: String;
  2682. begin
  2683. Result:=HTMLTagNames[ElementTag];
  2684. end;
  2685. { TDivWidget }
  2686. constructor TDivWidget.Create(aOwner: TComponent);
  2687. begin
  2688. inherited Create(aOwner);
  2689. ElementTag:=etDiv;
  2690. end;
  2691. constructor TParagraphWidget.Create(aOwner: TComponent);
  2692. begin
  2693. inherited Create(aOwner);
  2694. ElementTag:=etP;
  2695. end;
  2696. end.