Web.st 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185
  1. Smalltalk createPackage: 'Web'!
  2. Object subclass: #BrowserInterface
  3. instanceVariableNames: ''
  4. package: 'Web'!
  5. !BrowserInterface commentStamp!
  6. I am platform interface class that tries to use window and jQuery; that is, one for browser environment.
  7. ## API
  8. self isAvailable. "true if window and jQuery exist".
  9. self alert: 'Hey, there is a problem'.
  10. self confirm: 'Affirmative?'.
  11. self prompt: 'Your name:'.
  12. self ajax: #{
  13. 'url' -> '/patch.js'. 'type' -> 'GET'. dataType->'script'
  14. }.!
  15. !BrowserInterface methodsFor: 'actions'!
  16. ajax: anObject
  17. ^ jQuery ajax: anObject
  18. !
  19. alert: aString
  20. ^ window alert: aString
  21. !
  22. confirm: aString
  23. ^ window confirm: aString
  24. !
  25. prompt: aString
  26. ^ window prompt: aString
  27. !
  28. prompt: aString default: defaultString
  29. ^ window prompt: aString default: defaultString
  30. ! !
  31. !BrowserInterface methodsFor: 'testing'!
  32. isAvailable
  33. <return typeof window !!== "undefined" && typeof jQuery !!== "undefined">
  34. ! !
  35. Object subclass: #HTMLCanvas
  36. instanceVariableNames: 'root'
  37. package: 'Web'!
  38. !HTMLCanvas commentStamp!
  39. I am a canvas for building HTML.
  40. I provide the `#tag:` method to create a `TagBrush` (wrapping a DOM element) and convenience methods in the `tags` protocol.
  41. ## API
  42. My instances are used as the argument of the `#renderOn:` method of `Widget` objects.
  43. The `#with:` method is used to compose HTML, nesting tags. `#with:` can take a `TagBrush`, a `String`, a `BlockClosure` or a `Widget` as argument.
  44. ## Usage example:
  45. aCanvas a
  46. with: [ aCanvas span with: 'click me' ];
  47. onClick: [ window alert: 'clicked!!' ]!
  48. !HTMLCanvas methodsFor: 'accessing'!
  49. root
  50. ^ root
  51. !
  52. root: aTagBrush
  53. root := aTagBrush
  54. !
  55. snippet: anElement
  56. "Adds clone of anElement, finds [data-snippet=""*""] subelement
  57. and returns TagBrush as if that subelement was just added.
  58. Rarely needed to use directly, use `html foo` dynamically installed method
  59. for a snippet named foo."
  60. | clone caret |
  61. clone := anElement asJQuery clone.
  62. self with: (TagBrush fromJQuery: clone canvas: self).
  63. caret := clone find: '[data-snippet="*"]'.
  64. caret toArray isEmpty ifTrue: [ caret := clone ].
  65. ^ TagBrush fromJQuery: (caret removeAttr: 'data-snippet') canvas: self
  66. ! !
  67. !HTMLCanvas methodsFor: 'adding'!
  68. entity: aString
  69. "Adds a character representing html entity, eg.
  70. html entity: 'copy'
  71. adds a copyright sign.
  72. If a name does not represent valid HTML entity, error is raised."
  73. | result |
  74. result := ('<span />' asJQuery html: '&', aString, ';') text.
  75. result size = 1 ifFalse: [ self error: 'Not an HTML entity: ', aString ].
  76. self with: result
  77. !
  78. with: anObject
  79. ^ self root with: anObject
  80. ! !
  81. !HTMLCanvas methodsFor: 'initialization'!
  82. initialize
  83. super initialize.
  84. root ifNil: [ root := TagBrush fromString: 'div' canvas: self ]
  85. !
  86. initializeFromJQuery: aJQuery
  87. root := TagBrush fromJQuery: aJQuery canvas: self
  88. ! !
  89. !HTMLCanvas methodsFor: 'tags'!
  90. a
  91. ^ self tag: 'a'
  92. !
  93. abbr
  94. ^ self tag: 'abbr'
  95. !
  96. address
  97. ^ self tag: 'address'
  98. !
  99. area
  100. ^ self tag: 'area'
  101. !
  102. article
  103. ^ self tag: 'article'
  104. !
  105. aside
  106. ^ self tag: 'aside'
  107. !
  108. audio
  109. ^ self tag: 'audio'
  110. !
  111. base
  112. ^ self tag: 'base'
  113. !
  114. blockquote
  115. ^ self tag: 'blockquote'
  116. !
  117. body
  118. ^ self tag: 'body'
  119. !
  120. br
  121. ^ self tag: 'br'
  122. !
  123. button
  124. ^ self tag: 'button'
  125. !
  126. canvas
  127. ^ self tag: 'canvas'
  128. !
  129. caption
  130. ^ self tag: 'caption'
  131. !
  132. cite
  133. ^ self tag: 'cite'
  134. !
  135. code
  136. ^ self tag: 'code'
  137. !
  138. col
  139. ^ self tag: 'col'
  140. !
  141. colgroup
  142. ^ self tag: 'colgroup'
  143. !
  144. command
  145. ^ self tag: 'command'
  146. !
  147. datalist
  148. ^ self tag: 'datalist'
  149. !
  150. dd
  151. ^ self tag: 'dd'
  152. !
  153. del
  154. ^ self tag: 'del'
  155. !
  156. details
  157. ^ self tag: 'details'
  158. !
  159. div
  160. ^ self tag: 'div'
  161. !
  162. div: aBlock
  163. ^ self div with: aBlock
  164. !
  165. dl
  166. ^ self tag: 'dl'
  167. !
  168. dt
  169. ^ self tag: 'dt'
  170. !
  171. em
  172. ^ self tag: 'em'
  173. !
  174. embed
  175. ^ self tag: 'embed'
  176. !
  177. fieldset
  178. ^ self tag: 'fieldset'
  179. !
  180. figcaption
  181. ^ self tag: 'figcaption'
  182. !
  183. figure
  184. ^ self tag: 'figure'
  185. !
  186. footer
  187. ^ self tag: 'footer'
  188. !
  189. form
  190. ^ self tag: 'form'
  191. !
  192. h1
  193. ^ self tag: 'h1'
  194. !
  195. h1: anObject
  196. ^ self h1 with: anObject
  197. !
  198. h2
  199. ^ self tag: 'h2'
  200. !
  201. h2: anObject
  202. ^ self h2 with: anObject
  203. !
  204. h3
  205. ^ self tag: 'h3'
  206. !
  207. h3: anObject
  208. ^ self h3 with: anObject
  209. !
  210. h4
  211. ^ self tag: 'h4'
  212. !
  213. h4: anObject
  214. ^ self h4 with: anObject
  215. !
  216. h5
  217. ^ self tag: 'h5'
  218. !
  219. h5: anObject
  220. ^ self h5 with: anObject
  221. !
  222. h6
  223. ^ self tag: 'h6'
  224. !
  225. h6: anObject
  226. ^ self h6 with: anObject
  227. !
  228. head
  229. ^ self tag: 'head'
  230. !
  231. header
  232. ^ self tag: 'header'
  233. !
  234. hgroup
  235. ^ self tag: 'hgroup'
  236. !
  237. hr
  238. ^ self tag: 'hr'
  239. !
  240. html
  241. ^ self tag: 'html'
  242. !
  243. iframe
  244. ^ self tag: 'iframe'
  245. !
  246. iframe: aString
  247. ^ self iframe src: aString
  248. !
  249. img
  250. ^ self tag: 'img'
  251. !
  252. img: aString
  253. ^ self img src: aString
  254. !
  255. input
  256. ^ self tag: 'input'
  257. !
  258. label
  259. ^ self tag: 'label'
  260. !
  261. legend
  262. ^ self tag: 'legend'
  263. !
  264. li
  265. ^ self tag: 'li'
  266. !
  267. li: anObject
  268. ^ self li with: anObject
  269. !
  270. link
  271. ^ self tag: 'link'
  272. !
  273. map
  274. ^ self tag: 'map'
  275. !
  276. mark
  277. ^ self tag: 'mark'
  278. !
  279. menu
  280. ^ self tag: 'menu'
  281. !
  282. meta
  283. ^ self tag: 'meta'
  284. !
  285. nav
  286. ^ self tag: 'nav'
  287. !
  288. newTag: aString
  289. ^ TagBrush fromString: aString canvas: self
  290. !
  291. noscript
  292. ^ self tag: 'noscript'
  293. !
  294. object
  295. ^ self tag: 'object'
  296. !
  297. ol
  298. ^ self tag: 'ol'
  299. !
  300. ol: anObject
  301. ^ self ol with: anObject
  302. !
  303. optgroup
  304. ^ self tag: 'optgroup'
  305. !
  306. option
  307. ^ self tag: 'option'
  308. !
  309. output
  310. ^ self tag: 'output'
  311. !
  312. p
  313. ^ self tag: 'p'
  314. !
  315. p: anObject
  316. ^ self p with: anObject
  317. !
  318. param
  319. ^ self tag: 'param'
  320. !
  321. pre
  322. ^ self tag: 'pre'
  323. !
  324. progress
  325. ^ self tag: 'progress'
  326. !
  327. script
  328. ^ self tag: 'script'
  329. !
  330. section
  331. ^ self tag: 'section'
  332. !
  333. select
  334. ^ self tag: 'select'
  335. !
  336. small
  337. ^ self tag: 'small'
  338. !
  339. source
  340. ^ self tag: 'source'
  341. !
  342. span
  343. ^ self tag: 'span'
  344. !
  345. span: anObject
  346. ^ self span with: anObject
  347. !
  348. strong
  349. ^ self tag: 'strong'
  350. !
  351. strong: anObject
  352. ^ self strong with: anObject
  353. !
  354. style
  355. ^ self tag: 'style'
  356. !
  357. style: aString
  358. ^ self style with: aString; yourself
  359. !
  360. sub
  361. ^ self tag: 'sub'
  362. !
  363. summary
  364. ^ self tag: 'summary'
  365. !
  366. sup
  367. ^ self tag: 'sup'
  368. !
  369. table
  370. ^ self tag: 'table'
  371. !
  372. tag: aString
  373. ^ root addBrush: (self newTag: aString)
  374. !
  375. tbody
  376. ^ self tag: 'tbody'
  377. !
  378. td
  379. ^ self tag: 'td'
  380. !
  381. textarea
  382. ^ self tag: 'textarea'
  383. !
  384. tfoot
  385. ^ self tag: 'tfoot'
  386. !
  387. th
  388. ^ self tag: 'th'
  389. !
  390. thead
  391. ^ self tag: 'thead'
  392. !
  393. time
  394. ^ self tag: 'time'
  395. !
  396. title
  397. ^ self tag: 'title'
  398. !
  399. tr
  400. ^ self tag: 'tr'
  401. !
  402. ul
  403. ^ self tag: 'ul'
  404. !
  405. ul: anObject
  406. ^ self ul with: anObject
  407. !
  408. video
  409. ^ self tag: 'video'
  410. ! !
  411. !HTMLCanvas class methodsFor: 'initialization'!
  412. initialize
  413. "Allow JS method calls for the jQuery object.
  414. See boot.js DNU handling."
  415. Smalltalk optOut: jQuery
  416. ! !
  417. !HTMLCanvas class methodsFor: 'instance creation'!
  418. onJQuery: aJQuery
  419. ^ self basicNew
  420. initializeFromJQuery: aJQuery;
  421. initialize;
  422. yourself
  423. ! !
  424. Object subclass: #HTMLSnippet
  425. instanceVariableNames: 'snippets'
  426. package: 'Web'!
  427. !HTMLSnippet commentStamp!
  428. My sole instance is the registry of html snippets.
  429. `HTMLSnippet current` is the public singleton instance.
  430. On startup, it scans the document for any html elements
  431. with `'data-snippet="foo"'` attribute and takes them off the document,
  432. remembering them in the store under the specified name.
  433. It also install method #foo into HTMLCanvas dynamically.
  434. Every html snippet should mark a 'caret', a place where contents
  435. can be inserted, by 'data-snippet="*"' (a special name for caret).
  436. For example:
  437. `<li data-snippet='menuelement' class='...'><a data-snippet='*'></a></li>`
  438. defines a list element with a link inside; the link itself is marked as a caret.
  439. You can later issue
  440. `html menuelement href: '/foo'; with: 'A foo'`
  441. to insert the whole snippet and directly manipulate the caret, so it renders:
  442. `<li class='...'><a href='/foo'>A foo</a></li>`
  443. For a self-careting tags (not very useful, but you do not need to fill class etc.
  444. you can use
  445. `<div class='lots of classes' attr1='one' attr2='two' data-snippet='*bar'></div>`
  446. and in code later do:
  447. `html bar with: [ xxx ]`
  448. to render
  449. `<div class='lots of classes' attr1='one' attr2='two'>...added by xxx...</div>`!
  450. !HTMLSnippet methodsFor: 'accessing'!
  451. snippetAt: aString
  452. ^ self snippets at: aString
  453. !
  454. snippets
  455. ^ snippets ifNil: [ snippets := #{} ]
  456. ! !
  457. !HTMLSnippet methodsFor: 'initialization'!
  458. initializeFromJQuery: aJQuery
  459. "Finds and takes out all snippets out of aJQuery.
  460. Installs it into self."
  461. (self snippetsFromJQuery: aJQuery) do: [ :each |
  462. self installSnippetFromJQuery: each asJQuery ]
  463. ! !
  464. !HTMLSnippet methodsFor: 'method generation'!
  465. snippetAt: aString compile: anElement
  466. "Method generation for the snippet.
  467. The selector is aString, the method block uses anElement"
  468. ClassBuilder new
  469. installMethod: ([ :htmlReceiver | htmlReceiver snippet: anElement ]
  470. currySelf asCompiledMethod: aString)
  471. forClass: HTMLCanvas
  472. protocol: '**snippets'
  473. ! !
  474. !HTMLSnippet methodsFor: 'private'!
  475. snippetsFromJQuery: aJQuery
  476. ^ (aJQuery find: '[data-snippet]') toArray
  477. ! !
  478. !HTMLSnippet methodsFor: 'snippet installation'!
  479. installSnippetFromJQuery: element
  480. | name |
  481. name := element attr: 'data-snippet'.
  482. name = '*' ifFalse: [
  483. ('^\*' asRegexp test: name)
  484. ifTrue: [
  485. name := name allButFirst.
  486. element attr: 'data-snippet' put: '*' ]
  487. ifFalse: [
  488. element removeAttr: 'data-snippet' ].
  489. self snippetAt: name install: (element detach get: 0) ]
  490. !
  491. snippetAt: aString install: anElement
  492. self snippets at: aString put: anElement.
  493. self snippetAt: aString compile: anElement
  494. ! !
  495. HTMLSnippet class instanceVariableNames: 'current'!
  496. !HTMLSnippet class methodsFor: 'initialization'!
  497. ensureCurrent
  498. current ifNil: [
  499. current := super new
  500. initializeFromJQuery: document asJQuery;
  501. yourself ]
  502. !
  503. initialize
  504. super initialize.
  505. self isDOMAvailable ifTrue: [
  506. self ensureCurrent ]
  507. ! !
  508. !HTMLSnippet class methodsFor: 'instance creation'!
  509. current
  510. ^ current
  511. !
  512. isDOMAvailable
  513. < return typeof document !!== 'undefined' >
  514. !
  515. new
  516. self shouldNotImplement
  517. ! !
  518. Object subclass: #TagBrush
  519. instanceVariableNames: 'canvas element'
  520. package: 'Web'!
  521. !TagBrush commentStamp!
  522. I am a brush for building a single DOM element (which I hold onto).
  523. All tags but `<style>` are instances of me (see the `StyleBrush` class).
  524. ## API
  525. 1. Nesting
  526. Use `#with:` to nest tags. `#with:` can take aString, `TagBrush` instance, a `Widget` or block closure as parameter.
  527. Example: `aTag with: aString with: aCanvas div`
  528. 2. Events
  529. The `events` protocol contains all methods related to events (delegating event handling to jQuery).
  530. Example: `aTag onClick: [ window alert: 'clicked' ]`
  531. 3. Attributes
  532. The `attribute` protocol contains methods for attribute manipulation (delegating to jQuery too).
  533. Example: `aTag at: 'value' put: 'hello world'`
  534. 4. Raw access and jQuery
  535. The `#element` method can be used to access to JavaScript DOM element object.
  536. Example: `aTag element cssStyle`
  537. Use `#asJQuery` to access to the receiver converted into a jQuery object.
  538. Example: `aTag asJQuery css: 'color' value: 'red'`!
  539. !TagBrush methodsFor: 'accessing'!
  540. element
  541. ^ element
  542. ! !
  543. !TagBrush methodsFor: 'adding'!
  544. addBrush: aTagBrush
  545. self appendChild: aTagBrush element.
  546. ^ aTagBrush
  547. !
  548. append: anObject
  549. anObject appendToBrush: self
  550. !
  551. appendBlock: aBlock
  552. | root |
  553. root := canvas root.
  554. canvas root: self.
  555. aBlock value: canvas.
  556. canvas root: root
  557. !
  558. appendChild: anElement
  559. "In IE7 and IE8 appendChild fails on several node types. So we need to check"
  560. <var element=self['@element'];
  561. if (null == element.canHaveChildren || element.canHaveChildren) {
  562. element.appendChild(anElement);
  563. } else {
  564. element.text = String(element.text) + anElement.innerHTML;
  565. } >
  566. !
  567. appendString: aString
  568. self appendChild: (self createTextNodeFor: aString)
  569. !
  570. appendToBrush: aTagBrush
  571. aTagBrush addBrush: self
  572. !
  573. contents: anObject
  574. self
  575. empty;
  576. append: anObject
  577. !
  578. empty
  579. self asJQuery empty
  580. !
  581. with: anObject
  582. self append: anObject
  583. ! !
  584. !TagBrush methodsFor: 'attributes'!
  585. accesskey: aString
  586. self at: 'accesskey' put: aString
  587. !
  588. action: aString
  589. self at: 'action' put: aString
  590. !
  591. align: aString
  592. self at: 'align' put: aString
  593. !
  594. alt: aString
  595. self at: 'alt' put: aString
  596. !
  597. at: aString
  598. ^ self at: aString ifAbsent: [ Collection new errorNotFound ]
  599. !
  600. at: aString ifAbsent: aBlock
  601. <return self['@element'].hasAttribute(aString) ? self['@element'].getAttribute(aString) : aBlock._value()>
  602. !
  603. at: aString put: aValue
  604. <self['@element'].setAttribute(aString, aValue); return aValue>
  605. !
  606. class: aString
  607. <self['@element'].className = aString>
  608. !
  609. cols: aString
  610. self at: 'cols' put: aString
  611. !
  612. contenteditable: aString
  613. self at: 'contenteditable' put: aString
  614. !
  615. contextmenu: aString
  616. self at: 'contextmenu' put: aString
  617. !
  618. draggable: aString
  619. self at: 'draggable' put: aString
  620. !
  621. for: aString
  622. self at: 'for' put: aString
  623. !
  624. height: aString
  625. self at: 'height' put: aString
  626. !
  627. hidden
  628. self at: 'hidden' put: 'hidden'
  629. !
  630. href: aString
  631. self at: 'href' put: aString
  632. !
  633. id: aString
  634. self at: 'id' put: aString
  635. !
  636. media: aString
  637. self at: 'media' put: aString
  638. !
  639. method: aString
  640. self at: 'method' put: aString
  641. !
  642. name: aString
  643. self at: 'name' put: aString
  644. !
  645. placeholder: aString
  646. self at: 'placeholder' put: aString
  647. !
  648. rel: aString
  649. self at: 'rel' put: aString
  650. !
  651. removeAt: aString
  652. <self['@element'].removeAttribute(aString)>
  653. !
  654. rows: aString
  655. self at: 'rows' put: aString
  656. !
  657. src: aString
  658. self at: 'src' put: aString
  659. !
  660. style: aString
  661. self at: 'style' put: aString
  662. !
  663. tabindex: aNumber
  664. self at: 'tabindex' put: aNumber
  665. !
  666. target: aString
  667. self at: 'target' put: aString
  668. !
  669. title: aString
  670. self at: 'title' put: aString
  671. !
  672. type: aString
  673. self at: 'type' put: aString
  674. !
  675. valign: aString
  676. self at: 'valign' put: aString
  677. !
  678. value: aString
  679. self at: 'value' put: aString
  680. !
  681. width: aString
  682. self at: 'width' put: aString
  683. ! !
  684. !TagBrush methodsFor: 'converting'!
  685. asJQuery
  686. ^ self element asJQuery
  687. !
  688. asJQueryInContext: aContext
  689. ^ self element asJQueryInContext: aContext
  690. ! !
  691. !TagBrush methodsFor: 'events'!
  692. onBlur: aBlock
  693. self asJQuery bind: 'blur' do: aBlock
  694. !
  695. onChange: aBlock
  696. self asJQuery bind: 'change' do: aBlock
  697. !
  698. onClick: aBlock
  699. self asJQuery bind: 'click' do: aBlock
  700. !
  701. onDblClick: aBlock
  702. self asJQuery bind: 'dblclick' do: aBlock
  703. !
  704. onFocus: aBlock
  705. self asJQuery bind: 'focus' do: aBlock
  706. !
  707. onFocusIn: aBlock
  708. self asJQuery bind: 'focusin' do: aBlock
  709. !
  710. onFocusOut: aBlock
  711. self asJQuery bind: 'focusout' do: aBlock
  712. !
  713. onHover: aBlock
  714. self asJQuery bind: 'hover' do: aBlock
  715. !
  716. onKeyDown: aBlock
  717. self asJQuery bind: 'keydown' do: aBlock
  718. !
  719. onKeyPress: aBlock
  720. self asJQuery bind: 'keypress' do: aBlock
  721. !
  722. onKeyUp: aBlock
  723. self asJQuery bind: 'keyup' do: aBlock
  724. !
  725. onMouseDown: aBlock
  726. self asJQuery bind: 'mousedown' do: aBlock
  727. !
  728. onMouseEnter: aBlock
  729. self asJQuery bind: 'mouseenter' do: aBlock
  730. !
  731. onMouseLeave: aBlock
  732. self asJQuery bind: 'mouseleave' do: aBlock
  733. !
  734. onMouseMove: aBlock
  735. self asJQuery bind: 'mousemove' do: aBlock
  736. !
  737. onMouseOut: aBlock
  738. self asJQuery bind: 'mouseout' do: aBlock
  739. !
  740. onMouseOver: aBlock
  741. self asJQuery bind: 'mouseover' do: aBlock
  742. !
  743. onMouseUp: aBlock
  744. self asJQuery bind: 'mouseup' do: aBlock
  745. !
  746. onSelect: aBlock
  747. self asJQuery bind: 'select' do: aBlock
  748. !
  749. onSubmit: aBlock
  750. self asJQuery bind: 'submit' do: aBlock
  751. !
  752. onUnload: aBlock
  753. self asJQuery bind: 'unload' do: aBlock
  754. ! !
  755. !TagBrush methodsFor: 'initialization'!
  756. initializeFromJQuery: aJQuery canvas: aCanvas
  757. element := aJQuery get: 0.
  758. canvas := aCanvas
  759. !
  760. initializeFromString: aString canvas: aCanvas
  761. element := self createElementFor: aString.
  762. canvas := aCanvas
  763. ! !
  764. !TagBrush methodsFor: 'private'!
  765. appendDocumentFragment: anElement
  766. <var element=self['@element'].appendChild(anElement["@element"])>
  767. !
  768. createElementFor: aString
  769. <return document.createElement(String(aString))>
  770. !
  771. createTextNodeFor: aString
  772. <return document.createTextNode(String(aString))>
  773. ! !
  774. !TagBrush class methodsFor: 'instance creation'!
  775. fromJQuery: aJQuery canvas: aCanvas
  776. ^ self new
  777. initializeFromJQuery: aJQuery canvas: aCanvas;
  778. yourself
  779. !
  780. fromString: aString canvas: aCanvas
  781. ^ self new
  782. initializeFromString: aString canvas: aCanvas;
  783. yourself
  784. ! !
  785. InterfacingObject subclass: #Widget
  786. instanceVariableNames: ''
  787. package: 'Web'!
  788. !Widget commentStamp!
  789. I am a presenter building HTML. Subclasses are typically reusable components.
  790. ## API
  791. Use `#renderContentOn:` to build HTML. (See `HTMLCanvas` and `TagBrush` classes for more about building HTML).
  792. To add a widget to the page, the convenience method `#appendToJQuery:` is very useful.
  793. Exemple:
  794. Counter new appendToJQuery: 'body' asJQuery!
  795. !Widget methodsFor: 'adding'!
  796. appendToBrush: aTagBrush
  797. self appendToJQuery: aTagBrush asJQuery
  798. !
  799. appendToJQuery: aJQuery
  800. self renderOn: (HTMLCanvas onJQuery: aJQuery)
  801. ! !
  802. !Widget methodsFor: 'rendering'!
  803. renderOn: html
  804. self
  805. ! !
  806. !Widget class methodsFor: 'accessing'!
  807. classTag
  808. "Returns a tag or general category for this class.
  809. Typically used to help tools do some reflection.
  810. Helios, for example, uses this to decide what icon the class should display."
  811. ^ 'widget'
  812. ! !
  813. !BlockClosure methodsFor: '*Web'!
  814. appendToBrush: aTagBrush
  815. aTagBrush appendBlock: self
  816. !
  817. appendToJQuery: aJQuery
  818. self value: (HTMLCanvas onJQuery: aJQuery)
  819. !
  820. asJQuery
  821. ^ {self} asJQuery
  822. !
  823. asJQueryInContext: aContext
  824. ^ {self} asJQueryInContext: aContext
  825. ! !
  826. !CharacterArray methodsFor: '*Web'!
  827. asSnippet
  828. ^ HTMLSnippet current snippetAt: self asString
  829. ! !
  830. !JSObjectProxy methodsFor: '*Web'!
  831. asJQuery
  832. <return jQuery(self['@jsObject'])>
  833. !
  834. asJQueryInContext: aContext
  835. <return jQuery(self['@jsObject'], aContext)>
  836. ! !
  837. !Object methodsFor: '*Web'!
  838. appendToBrush: aTagBrush
  839. aTagBrush append: self asString
  840. !
  841. appendToJQuery: aJQuery
  842. aJQuery append: self asString
  843. !
  844. asJQuery
  845. <return jQuery(self)>
  846. !
  847. asJQueryInContext: aContext
  848. <return jQuery(self, aContext)>
  849. !
  850. postMessageTo: aFrame
  851. ^ self postMessageTo: aFrame origin: '*'
  852. !
  853. postMessageTo: aFrame origin: aString
  854. <return aFrame.postMessage(self, aString)>
  855. ! !
  856. !String methodsFor: '*Web'!
  857. appendToBrush: aTagBrush
  858. aTagBrush appendString: self
  859. !
  860. appendToJQuery: aJQuery
  861. aJQuery append: self
  862. !
  863. asJQuery
  864. <return jQuery(String(self))>
  865. !
  866. asJQueryInContext: aContext
  867. <return jQuery(String(self), aContext)>
  868. ! !