Web.st 18 KB

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