Package pyjamas :: Module DOM
[hide private]
[frames] | no frames]

Source Code for Module pyjamas.DOM

   1  # Copyright 2006 James Tauber and contributors 
   2  # 
   3  # Licensed under the Apache License, Version 2.0 (the "License"); 
   4  # you may not use this file except in compliance with the License. 
   5  # You may obtain a copy of the License at 
   6  # 
   7  #     http://www.apache.org/licenses/LICENSE-2.0 
   8  # 
   9  # Unless required by applicable law or agreed to in writing, software 
  10  # distributed under the License is distributed on an "AS IS" BASIS, 
  11  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  12  # See the License for the specific language governing permissions and 
  13  # limitations under the License. 
  14  """ 
  15      DOM implements the core of Pjamas-Desktop, providing access to 
  16      and management of the DOM model of the PyWebkitGtk window. 
  17  """ 
  18   
  19  import pyjd 
  20   
  21  if pyjd.is_desktop: 
  22      from pyjamas.Window import onResize, onClosing, onClosed 
  23      from __pyjamas__ import JS, doc, get_main_frame, wnd 
  24   
  25      currentEvent = None 
  26   
  27  sCaptureElem = None 
  28  sEventPreviewStack = [] 
  29   
  30  listeners = {} 
  31   
  32  from pyjamas.ui import Event 
  33  from pyjamas.ui.Event import ( 
  34      ONBLUR, 
  35      ONCHANGE, 
  36      ONCLICK, 
  37      ONCONTEXTMENU, 
  38      ONDBLCLICK, 
  39      ONERROR, 
  40      ONFOCUS, 
  41      ONKEYDOWN, 
  42      ONKEYPRESS, 
  43      ONKEYUP, 
  44      ONLOAD, 
  45      ONLOSECAPTURE, 
  46      ONMOUSEDOWN, 
  47      ONMOUSEMOVE, 
  48      ONMOUSEOUT, 
  49      ONMOUSEOVER, 
  50      ONMOUSEUP, 
  51      ONSCROLL, 
  52      ONINPUT 
  53  ) 
  54   
  55  ELEMENT_NODE = 1 
  56  TEXT_NODE = 3 
  57  DOCUMENT_NODE = 9 
  58   
59 -def get_listener(item):
60 if item is None: 61 return None 62 if hasattr(item, "__instance__"): 63 ret = listeners.get(item.__instance__) 64 else: 65 ret = listeners.get(hash(item)) 66 return ret
67 68
69 -def set_listener(item, listener):
70 if hasattr(item, "__instance__"): 71 listeners[item.__instance__] = listener 72 elif listener is None: 73 listeners.pop(hash(item)) 74 else: 75 listeners[hash(item)] = listener
76 77 # ugh, *spew*, *hurl* http://code.google.com/p/pyjamas/issues/detail?id=213 78 hack_timer_workaround_bug_button = None 79 80
81 -def init():
82 mf = get_main_frame() 83 mf._addWindowEventListener("click", browser_event_cb) 84 mf._addWindowEventListener("change", browser_event_cb) 85 mf._addWindowEventListener("mouseout", browser_event_cb) 86 mf._addWindowEventListener("mousedown", browser_event_cb) 87 mf._addWindowEventListener("mouseup", browser_event_cb) 88 mf._addWindowEventListener("resize", browser_event_cb) 89 mf._addWindowEventListener("keyup", browser_event_cb) 90 mf._addWindowEventListener("keydown", browser_event_cb) 91 mf._addWindowEventListener("keypress", browser_event_cb) 92 mf._addWindowEventListener("mousewheel", browser_event_cb)
93
94 -def _init_testing():
95 body = doc().getElementsByTagName("body")[0] 96 mf._addEventListener(body, "click", cb) 97 mf._addEventListener(body, "change", cb) 98 mf._addEventListener(body, "mouseout", cb) 99 mf._addEventListener(body, "mousedown", cb) 100 mf._addEventListener(body, "mouseup", cb) 101 mf._addEventListener(body, "mousemove", cb) 102 mf._addEventListener(body, "resize", cb) 103 mf._addEventListener(body, "keyup", cb) 104 mf._addEventListener(body, "keydown", cb) 105 mf._addEventListener(body, "keypress", cb)
106
107 -def _dispatchWindowEvent(sender, evt, useCap):
108 pass
109 110
111 -def _dispatchEvent(sender, evt, useCap):
112 113 if evt is None: 114 evt = wnd().event 115 else: 116 try: 117 sender = get_main_frame().gobject_wrap(sender) # webkit HACK! 118 evt = get_main_frame().gobject_wrap(evt) # webkit HACK! 119 except: 120 pass 121 listener = None 122 curElem = sender 123 124 #print "_dispatchEvent", sender, evt, evt.type 125 cap = getCaptureElement() 126 listener = get_listener(cap) 127 if cap and (listener is not None): 128 #print "capture _dispatchEvent", cap, listener 129 dispatchEvent(evt, cap, listener) 130 evt.stopPropagation() 131 return 132 133 while curElem and (get_listener(curElem) is None): 134 #print "no parent listener", curElem, getParent(curElem) 135 curElem = getParent(curElem) 136 if curElem and getNodeType(curElem) != 1: 137 curElem = None 138 139 listener = get_listener(curElem) 140 if listener is not None: 141 dispatchEvent(evt, curElem, listener)
142 143
144 -def _dispatchCapturedMouseEvent(evt):
145 146 #print "dcmsev" 147 if not _dispatchCapturedEvent(evt): 148 return 149 cap = getCaptureElement() 150 listener = get_listener(cap) 151 if cap and (listener is not None): 152 dispatchEvent(evt, cap, listener) 153 #print "dcmsev, stop propagation" 154 evt.stopPropagation()
155 156
157 -def _dispatchCapturedMouseoutEvent(evt):
158 cap = getCaptureElement() 159 #print "cap", evt, cap 160 if cap is None: 161 return 162 #print "cap", evt, cap 163 if eventGetToElement(evt): 164 return 165 #print "synthesise", cap 166 #When the mouse leaves the window during capture, release capture 167 #and synthesize an 'onlosecapture' event. 168 setCapture(None) 169 listener = get_listener(cap) 170 if listener is None: 171 return 172 # this should be interesting... 173 #print "lose capture synthesised" 174 lcEvent = doc().createEvent('UIEvent') 175 lcEvent.initUIEvent('losecapture', False, False, wnd(), 0) 176 dispatchEvent(lcEvent, cap, listener)
177 178
179 -def browser_event_cb(view, event, from_window):
180 181 global sCaptureElem 182 #print "sCaptureElem", sCaptureElem 183 if event is None: 184 event = wnd().event 185 else: 186 try: 187 event = get_main_frame().gobject_wrap(event) # webkit HACK! 188 except: 189 pass 190 191 #print "browser_event_cb", event 192 et = eventGetType(event) 193 #print "browser_event_cb", event, et 194 if et == "resize": 195 onResize() 196 return 197 if et == 'mouseout': 198 #print "mouse out", event 199 _dispatchCapturedMouseoutEvent(event) 200 if (et == 'keyup' or et == 'keydown' or 201 et == 'keypress' or et == 'change'): 202 return _dispatchCapturedEvent(event) 203 else: 204 return _dispatchCapturedMouseEvent(event)
205 206
207 -def _dispatchCapturedEvent(event):
208 209 if not previewEvent(event): 210 #print "dce, stop propagation" 211 event.stopPropagation() 212 eventPreventDefault(event) 213 return False 214 return True
215 216
217 -def addEventPreview(preview):
218 sEventPreviewStack.append(preview)
219 220
221 -def appendChild(parent, child):
222 #print "appendChild", parent, child 223 parent.appendChild(child)
224
225 -def removeChild(parent, child):
226 #print "removeChild", parent, child 227 parent.removeChild(child)
228 #print "after removeChild", parent, child 229
230 -def replaceChild(parent, newChild, oldChild):
231 parent.replaceChild(newChild, oldChild)
232 233
234 -def buttonClick(element):
235 evt = doc().createEvent('MouseEvents') 236 evt.initMouseEvent("click", True, True, wnd(), 1, 0, 0, 0, 0, False, 237 False, False, False, 0, element) 238 element.dispatchEvent(evt)
239 240
241 -def compare(elem1, elem2):
242 if hasattr(elem1, "isSameNode") and hasattr(elem2, "isSameNode"): 243 return elem1.isSameNode(elem2) 244 return elem1 == elem2
245 246
247 -def createAnchor():
248 return createElement("A")
249 250
251 -def createButton():
252 return createElement("button")
253 254
255 -def createCol():
256 return createElement("col")
257 258
259 -def createDiv():
260 return createElement("div")
261 262
263 -def createElement(tag):
264 return doc().createElement(tag)
265 266
267 -def createFieldSet():
268 return createElement("fieldset")
269 270
271 -def createForm():
272 return createElement("form")
273 274
275 -def createIFrame():
276 return createElement("iframe")
277 278
279 -def createImg():
280 return createElement("img")
281 282
283 -def createInputCheck():
284 return createInputElement("checkbox")
285 286
287 -def createInputElement(elementType):
288 e = createElement("input") 289 e.type = elementType 290 return e
291 292
293 -def createInputPassword():
294 return createInputElement("password")
295 296
297 -def createInputRadio(group):
298 e = createInputElement('radio') 299 e.name = group 300 return e
301 302
303 -def createInputText():
304 return createInputElement("text")
305 306
307 -def createLabel():
308 return createElement("label")
309 310
311 -def createLegend():
312 return createElement("legend")
313 314
315 -def createOptions():
316 return createElement("options")
317 318
319 -def createSelect():
320 return createElement("select")
321 322
323 -def createSpan():
324 return createElement("span")
325 326
327 -def createTable():
328 return createElement("table")
329 330
331 -def createTBody():
332 return createElement("tbody")
333 334
335 -def createTD():
336 return createElement("td")
337 338
339 -def createTextArea():
340 return createElement("textarea")
341 342
343 -def createTH():
344 return createElement("th")
345 346
347 -def createTR():
348 return createElement("tr")
349 350
351 -def eventStopPropagation(evt):
352 evt.stopPropagation()
353 354
355 -def eventCancelBubble(evt, cancel):
356 evt.cancelBubble = cancel
357 358
359 -def eventGetAltKey(evt):
360 return evt.altKey
361 362
363 -def eventGetButton(evt):
364 return evt.button
365 366
367 -def eventGetClientX(evt):
368 return evt.clientX
369 370
371 -def eventGetClientY(evt):
372 return evt.clientY
373 374
375 -def eventGetCtrlKey(evt):
376 return evt.ctrlKey
377 378
379 -def eventGetFromElement(evt):
380 try: 381 return evt.fromElement 382 except: 383 return None
384 385
386 -def eventGetKeyCode(evt):
387 return evt.which or evt.keyCode or 0
388 389
390 -def eventGetRepeat(evt):
391 return evt.repeat
392 393
394 -def eventGetScreenX(evt):
395 return evt.screenX
396 397
398 -def eventGetScreenY(evt):
399 return evt.screenY
400 401
402 -def eventGetShiftKey(evt):
403 return evt.shiftKey
404 405
406 -def eventGetCurrentTarget(event):
407 return event.currentTarget
408 409
410 -def eventGetTarget(event):
411 return event.target
412 413
414 -def eventGetToElement(evt):
415 type = eventGetType(evt) 416 if type == 'mouseout': 417 return evt.relatedTarget 418 elif type == 'mouseover': 419 return evt.target 420 return None
421 422
423 -def eventGetType(event):
424 return event.type
425
426 -def eventGetTypeInt(event):
427 return Event.eventmap.get(str(event.type), 0)
428 429
430 -def eventGetTypeString(event):
431 return eventGetType(event)
432 433
434 -def eventPreventDefault(evt):
435 evt.preventDefault()
436 437
438 -def eventSetKeyCode(evt, key):
439 evt.keyCode = key
440 441
442 -def eventToString(evt):
443 return evt.toString()
444 445
446 -def iframeGetSrc(elem):
447 return elem.src
448 449
450 -def getAbsoluteLeft(elem):
451 left = 0 452 curr = elem 453 while curr.offsetParent: 454 left -= curr.scrollLeft 455 curr = curr.parentNode 456 457 while elem: 458 left += elem.offsetLeft - elem.scrollLeft 459 elem = elem.offsetParent 460 461 return left
462 463
464 -def getAbsoluteTop(elem):
465 top = 0 466 curr = elem 467 while curr.offsetParent: 468 top -= curr.scrollTop 469 curr = curr.parentNode 470 471 while elem: 472 top += elem.offsetTop - elem.scrollTop 473 elem = elem.offsetParent 474 475 return top
476 477
478 -def getAttribute(elem, attr):
479 attr = getattr(elem, attr) 480 if attr is None: 481 return None 482 return str(attr)
483 484
485 -def getElemAttribute(elem, attr):
486 mf = get_main_frame() 487 if not elem.hasAttribute(attr): 488 return str(getattr(elem, mf.mash_attrib(attr))) 489 return str(elem.getAttribute(attr))
490 491
492 -def getBooleanAttribute(elem, attr):
493 mf = get_main_frame() 494 return bool(getattr(elem, mf.mash_attrib(attr)))
495 496
497 -def getBooleanElemAttribute(elem, attr):
498 if not elem.hasAttribute(attr): 499 return None 500 return bool(elem.getAttribute(attr))
501 502
503 -def getCaptureElement():
504 global sCaptureElem 505 return sCaptureElem
506 507
508 -def getChild(elem, index):
509 """ 510 Get a child of the DOM element by specifying an index. 511 """ 512 count = 0 513 child = elem.firstChild 514 while child: 515 next = child.nextSibling 516 if child.nodeType == 1: 517 if index == count: 518 return child 519 count += 1 520 child = next 521 return None
522 523
524 -def getChildCount(elem):
525 """ 526 Calculate the number of children the given element has. This loops 527 over all the children of that element and counts them. 528 """ 529 count = 0 530 child = elem.firstChild 531 while child: 532 if child.nodeType == 1: 533 count += 1 534 child = child.nextSibling 535 return count
536 537
538 -def getChildIndex(parent, toFind):
539 """ 540 Return the index of the given child in the given parent. 541 542 This performs a linear search. 543 """ 544 count = 0 545 child = parent.firstChild 546 while child: 547 if child == toFind: 548 return count 549 if child.nodeType == 1: 550 count += 1 551 child = child.nextSibling 552 553 return -1
554 555
556 -def getElementById(id):
557 """ 558 Return the element in the document's DOM tree with the given id. 559 """ 560 return doc().getElementById(id)
561 562
563 -def getEventListener(element):
564 """ 565 See setEventListener() for more information. 566 """ 567 return get_listener(element)
568 569 eventbitsmap = {} 570 571
572 -def getEventsSunk(element):
573 """ 574 Return which events are currently "sunk" for a given DOM node. See 575 sinkEvents() for more information. 576 """ 577 return eventbitsmap.get(element, 0)
578 579
580 -def getFirstChild(elem):
581 child = elem and elem.firstChild 582 while child and child.nodeType != 1: 583 child = child.nextSibling 584 return child
585 586
587 -def getLastChild(elem):
588 child = elem and elem.lastChild 589 while child and child.nodeType != 1: 590 child = child.previousSibling 591 return child
592 593
594 -def getInnerHTML(element):
595 try: 596 return element and element.innerHtml # webkit. erk. 597 except: 598 return element and element.innerHTML # hulahop / xul. yuk.
599 600
601 -def getInnerText(element):
602 # To mimic IE's 'innerText' property in the W3C DOM, we need to recursively 603 # concatenate all child text nodes (depth first). 604 text = '' 605 child = element.firstChild 606 while child: 607 if child.nodeType == 1: 608 text += getInnerText(child) 609 elif child.nodeValue: 610 text += child.nodeValue 611 child = child.nextSibling 612 return text
613 614
615 -def getIntAttribute(elem, attr):
616 return int(getattr(elem, attr))
617 618
619 -def getIntElemAttribute(elem, attr):
620 if not elem.hasAttribute(attr): 621 return None 622 return int(elem.getAttribute(attr))
623 624
625 -def getIntStyleAttribute(elem, attr):
626 return getIntAttribute(elem.style, attr)
627 628
629 -def getPrevSibling(elem):
630 sib = elem.previousSibling 631 while sib and sib.nodeType != 1: 632 sib = sib.previousSibling 633 return sib
634 635
636 -def getNextSibling(elem):
637 sib = elem.nextSibling 638 while sib and sib.nodeType != 1: 639 sib = sib.nextSibling 640 return sib
641 642
643 -def getNodeType(elem):
644 return elem.nodeType
645 646
647 -def getParent(elem):
648 parent = elem.parentNode 649 if parent is None: 650 return None 651 if getNodeType(parent) != 1: 652 return None 653 return parent
654 655
656 -def getStyleAttribute(elem, attr):
657 try: 658 if hasattr(elem.style, 'getPropertyValue'): 659 return elem.style.getPropertyValue(mash_name_for_glib(attr)) 660 elif hasattr(elem.style, 'getProperty'): 661 return elem.style.getProperty(mash_name_for_glib(attr)) 662 return elem.style.getAttribute(attr) 663 except AttributeError: 664 return getattr(elem.style, attr, None)
665 666
667 -def insertChild(parent, toAdd, index):
668 count = 0 669 child = parent.firstChild 670 before = None 671 while child: 672 if child.nodeType == 1: 673 if (count == index): 674 before = child 675 break 676 677 count += 1 678 child = child.nextSibling 679 680 if before is None: 681 parent.appendChild(toAdd) 682 else: 683 parent.insertBefore(toAdd, before)
684 685
686 -class IterChildrenClass:
687
688 - def __init__(self, elem):
689 self.parent = elem 690 self.child = elem.firstChild 691 self.lastChild = None
692
693 - def next(self):
694 if not self.child: 695 raise StopIteration 696 self.lastChild = self.child 697 self.child = getNextSibling(self.child) 698 return self.lastChild
699
700 - def remove(self):
701 self.parent.removeChild(self.lastChild)
702
703 - def __iter__(self):
704 return self
705 706
707 -def iterChildren(elem):
708 """ 709 Returns an iterator over all the children of the given 710 DOM node. 711 """ 712 return IterChildrenClass(elem)
713 714
715 -class IterWalkChildren:
716
717 - def __init__(self, elem, all_nodes=False):
718 self.parent = elem 719 self.all_nodes = all_nodes 720 if all_nodes: 721 self.child = elem.firstChild 722 else: 723 self.child = getFirstChild(elem) 724 self.lastChild = None 725 self.stack = []
726
727 - def next(self):
728 if not self.child: 729 raise StopIteration 730 self.lastChild = self.child 731 if self.all_nodes: 732 firstChild = self.child.firstChild 733 nextSibling = self.child.nextSibling 734 else: 735 firstChild = getFirstChild(self.child) 736 nextSibling = getNextSibling(self.child) 737 if firstChild is not None: 738 if nextSibling is not None: 739 self.stack.append((nextSibling, self.parent)) 740 self.parent = self.child 741 self.child = firstChild 742 elif nextSibling is not None: 743 self.child = nextSibling 744 elif len(self.stack) > 0: 745 (self.child, self.parent) = self.stack.pop() 746 else: 747 self.child = None 748 return self.lastChild
749
750 - def remove(self):
751 self.parent.removeChild(self.lastChild)
752
753 - def __iter__(self):
754 return self
755 756
757 -def walkChildren(elem):
758 """ 759 Walk an entire subtree of the DOM. This returns an 760 iterator/iterable which performs a pre-order traversal 761 of all the children of the given element. 762 """ 763 return IterWalkChildren(elem)
764 765
766 -def isOrHasChild(parent, child):
767 while child: 768 if compare(parent, child): 769 return True 770 child = child.parentNode 771 if not child: 772 return False 773 if child.nodeType != 1: 774 child = None 775 return False
776 777
778 -def releaseCapture(elem):
779 #print "releaseCapture", elem 780 global sCaptureElem 781 if sCaptureElem and compare(elem, sCaptureElem): 782 sCaptureElem = None 783 releaseCapture_impl(elem) 784 return
785 786 # browser-specific overrides may implement this
787 -def releaseCapture_impl(elem): pass
788
789 -def removeEventPreview(preview):
790 sEventPreviewStack.remove(preview)
791 792
793 -def getOffsetHeight(elem):
794 return elem.offsetHeight
795 796
797 -def getOffsetWidth(elem):
798 return elem.offsetWidth
799 800
801 -def scrollIntoView(elem):
802 left = elem.offsetLeft 803 top = elem.offsetTop 804 width = elem.offsetWidth 805 height = elem.offsetHeight 806 807 if elem.parentNode != elem.offsetParent: 808 left -= elem.parentNode.offsetLeft 809 top -= elem.parentNode.offsetTop 810 811 cur = elem.parentNode 812 while cur and cur.nodeType == 1: 813 if hasattr(cur, 'style') and hasattr(cur.style, 'overflow') and \ 814 (cur.style.overflow == 'auto' or cur.style.overflow == 'scroll'): 815 if left < cur.scrollLeft: 816 cur.scrollLeft = left 817 if left + width > cur.scrollLeft + cur.clientWidth: 818 cur.scrollLeft = (left + width) - cur.clientWidth 819 if top < cur.scrollTop: 820 cur.scrollTop = top 821 if top + height > cur.scrollTop + cur.clientHeight: 822 cur.scrollTop = (top + height) - cur.clientHeight 823 824 offsetLeft = cur.offsetLeft 825 offsetTop = cur.offsetTop 826 if cur.parentNode != cur.offsetParent: 827 if hasattr(cur.parentNode, "offsetLeft"): 828 offsetLeft -= cur.parentNode.offsetLeft 829 if hasattr(cur.parentNode, "offsetTop"): 830 offsetTop -= cur.parentNode.offsetTop 831 832 left += offsetLeft - cur.scrollLeft 833 top += offsetTop - cur.scrollTop 834 cur = cur.parentNode
835 836
837 -def mash_name_for_glib(name, joiner='-'):
838 res = '' 839 for c in name: 840 if c.isupper(): 841 res += joiner + c.lower() 842 else: 843 res += c 844 return res
845 846
847 -def removeAttribute(element, attribute):
848 element.removeAttribute(attribute)
849 850
851 -def setAttribute(element, attribute, value):
852 #print element, attribute, value 853 setattr(element, attribute, value)
854 855
856 -def setElemAttribute(element, attribute, value):
857 element.setAttribute(attribute, value)
858 859
860 -def setBooleanAttribute(elem, attr, value):
861 mf = get_main_frame() 862 setattr(elem, mf.mash_attrib(attr), value)
863 864
865 -def setCapture(elem):
866 global sCaptureElem 867 sCaptureElem = elem 868 #print "setCapture", sCaptureElem 869 setCapture_impl(elem)
870 871 # browser-specific overrides may implement this
872 -def setCapture_impl(elem): pass
873
874 -def setEventListener(element, listener):
875 """ 876 Register an object to receive event notifications for the given 877 element. The listener's onBrowserEvent() method will be called 878 when a captured event occurs. To set which events are captured, 879 use sinkEvents(). 880 """ 881 set_listener(element, listener)
882 883
884 -def createTextNode(txt):
885 return doc().createTextNode(txt)
886 887
888 -def setInnerHTML(element, html):
889 try: 890 element.innerHtml = html # webkit. yuk. 891 except: 892 element.innerHTML = html # hulahop / xul. yukk.
893 894
895 -def setInnerText(elem, text):
896 #Remove all children first. 897 while elem.firstChild is not None: 898 elem.removeChild(elem.firstChild) 899 elem.appendChild(createTextNode(text or ''))
900 901
902 -def setIntElemAttribute(elem, attr, value):
903 elem.setAttribute(attr, str(value))
904 905
906 -def setIntAttribute(elem, attr, value):
907 setattr(elem, attr, int(value))
908 909
910 -def setIntStyleAttribute(elem, attr, value):
911 mf = get_main_frame() 912 if hasattr(elem.style, 'setProperty'): 913 elem.style.setProperty(mf.mash_attrib(attr), str(value), "") 914 else: 915 elem.style.setAttribute(mf.mash_attrib(attr), str(value), "")
916 917
918 -def setOptionText(select, text, index):
919 option = select.options.item(index) 920 option.textContent = text
921 922
923 -def setStyleAttribute(element, name, value):
924 if hasattr(element.style, 'setProperty'): 925 element.style.setProperty(mash_name_for_glib(name), value, "") 926 else: 927 element.style.setAttribute(name, value, "")
928
929 -def setStyleAttributes(element, **kwargs):
930 """ 931 multi attr: setStyleAttributes(self, {attr1:val1, attr2:val2, ...}) 932 """ 933 for attr, val in kwargs.items(): 934 if hasattr(element.style, 'setProperty'): 935 element.style.setProperty(mash_name_for_glib(attr), val, "") 936 else: 937 element.style.setAttribute(attr, val, "")
938
939 -def sinkEvents(element, bits):
940 """ 941 Set which events should be captured on a given element and passed to the 942 registered listener. To set the listener, use setEventListener(). 943 944 @param bits: A combination of bits; see ui.Event for bit values 945 """ 946 mask = getEventsSunk(element) ^ bits 947 eventbitsmap[element] = bits 948 if not mask: 949 return 950 951 bits = mask 952 953 if not bits: 954 return 955 mf = get_main_frame() 956 if hasattr(mf, "_addEventListener"): 957 aev = mf._addEventListener 958 else: 959 aev = mf.addEventListener 960 #cb = lambda x,y,z: _dispatchEvent(y) 961 cb = _dispatchEvent 962 963 # mozilla stupidly has DOMMouseScroll... 964 sinkEventsMozilla(element, bits) 965 966 bit = 1 967 while bits: 968 if bit > bits: 969 raise RuntimeError("sinkEvents: bit outruns bits") 970 if (bits & bit): 971 for event_name in Event.eventbits[bit][1]: 972 aev(element, event_name, cb) 973 bits ^= bit 974 bit <<= 1
975
976 -def sinkEventsMozilla(element, bits):
977 pass
978
979 -def toString(elem):
980 temp = elem.cloneNode(True) 981 tempDiv = createDiv() 982 tempDiv.appendChild(temp) 983 outer = getInnerHTML(tempDiv) 984 setInnerHTML(temp, "") 985 return outer
986 987 988 # TODO: missing dispatchEventAndCatch
989 -def dispatchEvent(event, element, listener):
990 dispatchEventImpl(event, element, listener)
991 992
993 -def previewEvent(evt):
994 #print "previewEvent", sEventPreviewStack 995 if len(sEventPreviewStack) == 0: 996 return True 997 preview = sEventPreviewStack[-1] 998 ret = preview.onEventPreview(evt) 999 if ret: 1000 return True 1001 1002 #print "previewEvent, cancel, prevent default" 1003 if evt: 1004 eventCancelBubble(evt, True) 1005 eventPreventDefault(evt) 1006 1007 return ret
1008 1009 1010 # TODO
1011 -def dispatchEventAndCatch(evt, elem, listener, handler):
1012 pass
1013 1014 currentEvent = None 1015 1016
1017 -def dispatchEventImpl(event, element, listener):
1018 global sCaptureElem 1019 global currentEvent 1020 if element == sCaptureElem: 1021 if eventGetType(event) == "losecapture": 1022 #print "lose capture" 1023 sCaptureElem = None 1024 #print "dispatchEventImpl", listener, eventGetType(event) 1025 prevCurrentEvent = currentEvent 1026 currentEvent = event 1027 listener.onBrowserEvent(event) 1028 currentEvent = prevCurrentEvent
1029 1030
1031 -def eventGetCurrentEvent():
1032 return currentEvent
1033 1034
1035 -def insertListItem(select, item, value, index):
1036 option = createElement("OPTION") 1037 setInnerText(option, item) 1038 if value is not None: 1039 setAttribute(option, "value", value) 1040 if index == -1: 1041 appendChild(select, option) 1042 else: 1043 insertChild(select, option, index)
1044 1045
1046 -def getBodyOffsetTop():
1047 return 0
1048 1049
1050 -def getBodyOffsetLeft():
1051 return 0
1052
1053 -def eventGetMouseWheelVelocityY(evt):
1054 """ these are all different, across all platforms! 1055 """ 1056 pass
1057 1058 1059 if not pyjd.is_desktop: 1060 init() 1061