-- PASSWORD BEHAVIOR -- -- -- © January 2001 - August 2005, OpenSpark Interactive Ltd -- ---------------------------------------------------------------------- -- 050803 JN: * Behavior ID can be set to #password or #confirm -- * SetText() and GetText() used for manipulating -- decrypted password -- * Password can now be pasted -- * #LogOn sent to all sprites when RETURN or ENTER is -- pressed -- 020304 JN: Support for text members added -- 011203 JN: Revised ---------------------------------------------------------------------- -- PROPERTY DECLARATIONS -- property ID -- property pMember property pType property pText property pPassword property pMaskChar -- LINGO EVENTS -- on beginSprite(me) me.mInitialize() end beginSprite on keyDown(me) me.mFilterInput() end keyDown on prepareFrame(me) me.mCheckForPaste() end prepareFrame -- PUBLIC METHODS -- on GetText(me, aList) ------------------------------------------------ -- OUTPUT: Returns the uncrypted contents of the current field. -------------------------------------------------------------------- case ilk(aList) of #list: aList.append(pPassword) #propList: aList[ID] = pPassword otherwise: aList = pPassword end case return aList end GetText on SetText(me, aPropList) -------------------------------------------- -- SOURCE: Sent by mCheckForPaste() -- INPUT: should be a property list with the format: -- [..., <#password|#confirm>: , ...] -- It may also be a string, if this instance's ID is -- #password -- ACTION: Sets pPassword and inserts the appropriate number of -- mask characters in the text member. -------------------------------------------------------------------- case ilk(aPropList) of #propList: vTemp = aPropList[ID] if stringP(vTemp) then pPassword = vTemp else exit end if #string: if ID = #password then pPassword = aPropList else exit end if otherwise: exit end case pText = "" tCount = pPassword.char.count i = tCount repeat while i pText = pText&pMaskChar i = i - 1 end repeat pMember.text = pText pMember.selection = [0, tCount] end SetText -- PRIVATE METHODS -- on mInitialize(me) --------------------------------------------------- -- Sent by beginSprite() -- -- ACTIONS: Sets initial properties and clears the field. -------------------------------------------------------------------- if voidP(ID) then ID = #password end if tSprite = sprite(me.spriteNum) pMember = tSprite.member --pMember.editable = TRUE pMember.autoTab = TRUE pType = pMember.type -- Define the character for masking passwords (platform-specific) if the platform contains "Mac" then pMaskChar = "•" else pMaskChar = "*" end if -- Empty the field me.mClearText() end mInitialize on mFilterInput(me) -------------------------------------------------- -- SOURCE: Sent by keyDown() -- ACTION: Replaces input with bullets or asterisks. Handles -- BACKSPACE and Delete correctly. -------------------------------------------------------------------- tKeyCode = the keyCode case tKeyCode of 48, 115, 116, 119, 121, 123, 124, 125, 126: -- Don't filter tab and arrow keys pass 36, 52: -- Don't allow RETURN or ENTER to show sendAllSprites(#LogOn) exit end case -- Update pPassword and place a substitute character in the field. -- The following is based on code by Irv Kalb (hopper-ex 15.03.99) if pType = #field then tStart = the selStart + 1 tFinish = the selEnd else tStart = pMember.selection[1] + 1 tFinish = pMember.selection[2] end if if tStart > tFinish then -- Insert case tKeyCode of 51: delete pPassword.char[tStart - 1] delete pText.char[tStart - 1] pass 117: delete pPassword.char[tStart] delete pText.char[tStart] pass otherwise put the key before char tStart of pPassword put pMaskChar before char tStart of pText pMember.text = pText end case else -- Replace case tKeyCode of 51, 117: delete pPassword.char[tStart..tFinish] pass otherwise put the key into char tStart to tFinish of pPassword put pMaskChar into char tStart to tFinish of pText pMember.text = pText end case end if if pType = #field then the selEnd = tStart the selStart = tStart else pMember.selection = [tStart, tStart] end if end mFilterInput on mClearText(me) ----------------------------------------------------- -- Sent by mInitialize() -- -- ACTION: Empties the field and sets appropriate properties -------------------------------------------------------------------- pText = "" pPassword = "" pMember.text = pText case pType of #field: the selStart = 0 #text: pMember.selection = [0, 0] end case end mClearText on mCheckForPaste(me) ------------------------------------------------ -- SOURCE: Sent by prepareFrame() -- ACTION: Detects when the user changes the text other than via a -- key press -------------------------------------------------------------------- if pMember.text <> pText then -- The user has pasted text into the member vPropList = [:] vPropList[ID] = pMember.text me.SetText(vPropList) put #paste end if end mCheckForPaste -- BEHAVIOR DESCRIPTION AND PARAMETERS -- on isOKToAttach(me, spriteType, spriteNumber) -- Allow only field members if spriteType = #graphic then case sprite(spriteNumber).member.type of #field, #text: return TRUE end case end if return FALSE end isOKToAttach on getPropertyDescriptionList(me) ------------------------------------ -- ACTION: Allows the user to set the ID properties -------------------------------------------------------------------- if the shiftDown then tProperties = [:] tProperties[ \ #ID] = [ \ #comment: "Field type", \ #format: #symbol, \ #range: [#password, #confirm], \ #default: #password \ ] return tProperties end if end getPropertyDescriptionList on getBehaviorTooltip(me) return \ "Attach this behavior to a Text or Field sprite."&RETURN&\ "Input will appear as an asterisk or bullet."&RETURN&\ "Use sendSprite(