123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955 |
- <%
- '
- ' Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
- ' For licensing, see LICENSE.html or http://ckeditor.com/license
- ' Shared variable for all instances ("static")
- dim CKEDITOR_initComplete
- dim CKEDITOR_returnedEvents
- ''
- ' \brief CKEditor class that can be used to create editor
- ' instances in ASP pages on server side.
- ' @see http://ckeditor.com
- '
- ' Sample usage:
- ' @code
- ' editor = new CKEditor
- ' editor.editor "editor1", "<p>Initial value.</p>", empty, empty
- ' @endcode
- Class CKEditor
- ''
- ' The version of %CKEditor.
- private version
- ''
- ' A constant string unique for each release of %CKEditor.
- private mTimeStamp
- ''
- ' URL to the %CKEditor installation directory (absolute or relative to document root).
- ' If not set, CKEditor will try to guess it's path.
- '
- ' Example usage:
- ' @code
- ' editor.basePath = "/ckeditor/"
- ' @endcode
- Public basePath
- ''
- ' A boolean variable indicating whether CKEditor has been initialized.
- ' Set it to true only if you have already included
- ' <script> tag loading ckeditor.js in your website.
- Public initialized
- ''
- ' Boolean variable indicating whether created code should be printed out or returned by a function.
- '
- ' Example 1: get the code creating %CKEditor instance and print it on a page with the "echo" function.
- ' @code
- ' editor = new CKEditor
- ' editor.returnOutput = true
- ' code = editor.editor("editor1", "<p>Initial value.</p>", empty, empty)
- ' response.write "<p>Editor 1:</p>"
- ' response.write code
- ' @endcode
- Public returnOutput
- ''
- ' A Dictionary with textarea attributes.
- '
- ' When %CKEditor is created with the editor() method, a HTML <textarea> element is created,
- ' it will be displayed to anyone with JavaScript disabled or with incompatible browser.
- public textareaAttributes
- ''
- ' A string indicating the creation date of %CKEditor.
- ' Do not change it unless you want to force browsers to not use previously cached version of %CKEditor.
- public timestamp
- ''
- ' A dictionary that holds the instance configuration.
- private oInstanceConfig
- ''
- ' A dictionary that holds the configuration for all the instances.
- private oAllInstancesConfig
- ''
- ' A dictionary that holds event listeners for the instance.
- private oInstanceEvents
- ''
- ' A dictionary that holds event listeners for all the instances.
- private oAllInstancesEvents
- ''
- ' A Dictionary that holds global event listeners (CKEDITOR object)
- private oGlobalEvents
- Private Sub Class_Initialize()
- version = "3.6.2"
- timeStamp = "B8DJ5M3"
- mTimeStamp = "B8DJ5M3"
- Set oInstanceConfig = CreateObject("Scripting.Dictionary")
- Set oAllInstancesConfig = CreateObject("Scripting.Dictionary")
- Set oInstanceEvents = CreateObject("Scripting.Dictionary")
- Set oAllInstancesEvents = CreateObject("Scripting.Dictionary")
- Set oGlobalEvents = CreateObject("Scripting.Dictionary")
- Set textareaAttributes = CreateObject("Scripting.Dictionary")
- textareaAttributes.Add "rows", 8
- textareaAttributes.Add "cols", 60
- End Sub
- ''
- ' Creates a %CKEditor instance.
- ' In incompatible browsers %CKEditor will downgrade to plain HTML <textarea> element.
- '
- ' @param name (string) Name of the %CKEditor instance (this will be also the "name" attribute of textarea element).
- ' @param value (string) Initial value.
- '
- ' Example usage:
- ' @code
- ' set editor = New CKEditor
- ' editor.editor "field1", "<p>Initial value.</p>"
- ' @endcode
- '
- ' Advanced example:
- ' @code
- ' set editor = new CKEditor
- ' set config = CreateObject("Scripting.Dictionary")
- ' config.Add "toolbar", Array( _
- ' Array( "Source", "-", "Bold", "Italic", "Underline", "Strike" ), _
- ' Array( "Image", "Link", "Unlink", "Anchor" ) _
- ' )
- ' set events = CreateObject("Scripting.Dictionary")
- ' events.Add "instanceReady", "function (evt) { alert('Loaded second editor: ' + evt.editor.name );}"
- ' editor.editor "field1", "<p>Initial value.</p>", config, events
- ' @endcode
- '
- public function editor(name, value)
- dim attr, out, js, customConfig, extraConfig
- dim attribute
- attr = ""
- for each attribute in textareaAttributes
- attr = attr & " " & attribute & "=""" & replace( textareaAttributes( attribute ), """", """ ) & """"
- next
- out = "<textarea name=""" & name & """" & attr & ">" & Server.HtmlEncode(value) & "</textarea>" & vbcrlf
- if not(initialized) then
- out = out & init()
- end if
- set customConfig = configSettings()
- js = returnGlobalEvents()
- extraConfig = (new JSON)( empty, customConfig, false )
- if extraConfig<>"" then extraConfig = ", " & extraConfig
- js = js & "CKEDITOR.replace('" & name & "'" & extraConfig & ");"
- out = out & script(js)
- if not(returnOutput) then
- response.write out
- out = ""
- end if
- editor = out
- oInstanceConfig.RemoveAll
- oInstanceEvents.RemoveAll
- end function
- ''
- ' Replaces a <textarea> with a %CKEditor instance.
- '
- ' @param id (string) The id or name of textarea element.
- '
- ' Example 1: adding %CKEditor to <textarea name="article"></textarea> element:
- ' @code
- ' set editor = New CKEditor
- ' editor.replace "article"
- ' @endcode
- '
- public function replaceInstance(id)
- dim out, js, customConfig, extraConfig
- out = ""
- if not(initialized) then
- out = out & init()
- end if
- set customConfig = configSettings()
- js = returnGlobalEvents()
- extraConfig = (new JSON)( empty, customConfig, false )
- if extraConfig<>"" then extraConfig = ", " & extraConfig
- js = js & "CKEDITOR.replace('" & id & "'" & extraConfig & ");"
- out = out & script(js)
- if not(returnOutput) then
- response.write out
- out = ""
- end if
- replaceInstance = out
- oInstanceConfig.RemoveAll
- oInstanceEvents.RemoveAll
- end function
- ''
- ' Replace all <textarea> elements available in the document with editor instances.
- '
- ' @param className (string) If set, replace all textareas with class className in the page.
- '
- ' Example 1: replace all <textarea> elements in the page.
- ' @code
- ' editor = new CKEditor
- ' editor.replaceAll empty
- ' @endcode
- '
- ' Example 2: replace all <textarea class="myClassName"> elements in the page.
- ' @code
- ' editor = new CKEditor
- ' editor.replaceAll 'myClassName'
- ' @endcode
- '
- function replaceAll(className)
- dim out, js, customConfig
- out = ""
- if not(initialized) then
- out = out & init()
- end if
- set customConfig = configSettings()
- js = returnGlobalEvents()
- if (customConfig.Count=0) then
- if (isEmpty(className)) then
- js = js & "CKEDITOR.replaceAll();"
- else
- js = js & "CKEDITOR.replaceAll('" & className & "');"
- end if
- else
- js = js & "CKEDITOR.replaceAll( function(textarea, config) {\n"
- if not(isEmpty(className)) then
- js = js & " var classRegex = new RegExp('(?:^| )' + '" & className & "' + '(?:$| )');\n"
- js = js & " if (!classRegex.test(textarea.className))\n"
- js = js & " return false;\n"
- end if
- js = js & " CKEDITOR.tools.extend(config, " & (new JSON)( empty, customConfig, false ) & ", true);"
- js = js & "} );"
- end if
- out = out & script(js)
- if not(returnOutput) then
- response.write out
- out = ""
- end if
- replaceAll = out
- oInstanceConfig.RemoveAll
- oInstanceEvents.RemoveAll
- end function
- ''
- ' A Dictionary that holds the %CKEditor configuration for all instances
- ' For the list of available options, see http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html
- '
- ' Example usage:
- ' @code
- ' editor.config("height") = 400
- ' // Use @@ at the beggining of a string to ouput it without surrounding quotes.
- ' editor.config("width") = "@@screen.width * 0.8"
- ' @endcode
- Public Property Let Config( configKey, configValue )
- oAllInstancesConfig.Add configKey, configValue
- End Property
- ''
- ' Configuration options for the next instance
- '
- Public Property Let instanceConfig( configKey, configValue )
- oInstanceConfig.Add configKey, configValue
- End Property
- ''
- ' Adds event listener.
- ' Events are fired by %CKEditor in various situations.
- '
- ' @param eventName (string) Event name.
- ' @param javascriptCode (string) Javascript anonymous function or function name.
- '
- ' Example usage:
- ' @code
- ' editor.addEventHandler "instanceReady", "function (ev) { " & _
- ' " alert('Loaded: ' + ev.editor.name); " & _
- ' "}"
- ' @endcode
- '
- public sub addEventHandler(eventName, javascriptCode)
- if not(oAllInstancesEvents.Exists( eventName ) ) then
- oAllInstancesEvents.Add eventName, Array()
- end if
- dim listeners, size
- listeners = oAllInstancesEvents( eventName )
- size = ubound(listeners) + 1
- redim preserve listeners(size)
- listeners(size) = javascriptCode
- oAllInstancesEvents( eventName ) = listeners
- ' '' Avoid duplicates. fixme...
- ' if (!in_array($javascriptCode, $this->_events[$event])) {
- ' $this->_events[$event][] = $javascriptCode;
- ' }
- end sub
- ''
- ' Clear registered event handlers.
- ' Note: this function will have no effect on already created editor instances.
- '
- ' @param eventName (string) Event name, if set to 'empty' all event handlers will be removed.
- '
- public sub clearEventHandlers( eventName )
- if not(isEmpty( eventName )) then
- oAllInstancesEvents.Remove eventName
- else
- oAllInstancesEvents.RemoveAll
- end if
- end sub
- ''
- ' Adds event listener only for the next instance.
- ' Events are fired by %CKEditor in various situations.
- '
- ' @param eventName (string) Event name.
- ' @param javascriptCode (string) Javascript anonymous function or function name.
- '
- ' Example usage:
- ' @code
- ' editor.addInstanceEventHandler "instanceReady", "function (ev) { " & _
- ' " alert('Loaded: ' + ev.editor.name); " & _
- ' "}"
- ' @endcode
- '
- public sub addInstanceEventHandler(eventName, javascriptCode)
- if not(oInstanceEvents.Exists( eventName ) ) then
- oInstanceEvents.Add eventName, Array()
- end if
- dim listeners, size
- listeners = oInstanceEvents( eventName )
- size = ubound(listeners) + 1
- redim preserve listeners(size)
- listeners(size) = javascriptCode
- oInstanceEvents( eventName ) = listeners
- ' '' Avoid duplicates. fixme...
- ' if (!in_array($javascriptCode, $this->_events[$event])) {
- ' $this->_events[$event][] = $javascriptCode;
- ' }
- end sub
- ''
- ' Clear registered event handlers.
- ' Note: this function will have no effect on already created editor instances.
- '
- ' @param eventName (string) Event name, if set to 'empty' all event handlers will be removed.
- '
- public sub clearInstanceEventHandlers( eventName )
- if not(isEmpty( eventName )) then
- oInstanceEvents.Remove eventName
- else
- oInstanceEvents.RemoveAll
- end if
- end sub
- ''
- ' Adds global event listener.
- '
- ' @param event (string) Event name.
- ' @param javascriptCode (string) Javascript anonymous function or function name.
- '
- ' Example usage:
- ' @code
- ' editor.addGlobalEventHandler "dialogDefinition", "function (ev) { " & _
- ' " alert('Loading dialog: ' + ev.data.name); " & _
- ' "}"
- ' @endcode
- '
- public sub addGlobalEventHandler( eventName, javascriptCode)
- if not(oGlobalEvents.Exists( eventName ) ) then
- oGlobalEvents.Add eventName, Array()
- end if
- dim listeners, size
- listeners = oGlobalEvents( eventName )
- size = ubound(listeners) + 1
- redim preserve listeners(size)
- listeners(size) = javascriptCode
- oGlobalEvents( eventName ) = listeners
- ' // Avoid duplicates.
- ' if (!in_array($javascriptCode, $this->_globalEvents[$event])) {
- ' $this->_globalEvents[$event][] = $javascriptCode;
- ' }
- end sub
- ''
- ' Clear registered global event handlers.
- ' Note: this function will have no effect if the event handler has been already printed/returned.
- '
- ' @param eventName (string) Event name, if set to 'empty' all event handlers will be removed .
- '
- public sub clearGlobalEventHandlers( eventName )
- if not(isEmpty( eventName )) then
- oGlobalEvents.Remove eventName
- else
- oGlobalEvents.RemoveAll
- end if
- end sub
- ''
- ' Prints javascript code.
- '
- ' @param string js
- '
- private function script(js)
- script = "<script type=""text/javascript"">" & _
- "//<![CDATA[" & vbcrlf & _
- js & vbcrlf & _
- "//]]>" & _
- "</script>" & vbcrlf
- end function
- ''
- ' Returns the configuration array (global and instance specific settings are merged into one array).
- '
- ' @param instanceConfig (Dictionary) The specific configurations to apply to editor instance.
- ' @param instanceEvents (Dictionary) Event listeners for editor instance.
- '
- private function configSettings()
- dim mergedConfig, mergedEvents
- set mergedConfig = cloneDictionary(oAllInstancesConfig)
- set mergedEvents = cloneDictionary(oAllInstancesEvents)
- if not(isEmpty(oInstanceConfig)) then
- set mergedConfig = mergeDictionary(mergedConfig, oInstanceConfig)
- end if
- if not(isEmpty(oInstanceEvents)) then
- for each eventName in oInstanceEvents
- code = oInstanceEvents( eventName )
- if not(mergedEvents.Exists( eventName)) then
- mergedEvents.Add eventName, code
- else
- dim listeners, size
- listeners = mergedEvents( eventName )
- size = ubound(listeners)
- if isArray( code ) then
- addedCount = ubound(code)
- redim preserve listeners( size + addedCount + 1 )
- for i = 0 to addedCount
- listeners(size + i + 1) = code (i)
- next
- else
- size = size + 1
- redim preserve listeners(size)
- listeners(size) = code
- end if
- mergedEvents( eventName ) = listeners
- end if
- next
- end if
- dim i, eventName, handlers, configON, ub, code
- if mergedEvents.Count>0 then
- if mergedConfig.Exists( "on" ) then
- set configON = mergedConfig.items( "on" )
- else
- set configON = CreateObject("Scripting.Dictionary")
- mergedConfig.Add "on", configOn
- end if
- for each eventName in mergedEvents
- handlers = mergedEvents( eventName )
- code = ""
- if isArray(handlers) then
- uB = ubound(handlers)
- if (uB = 0) then
- code = handlers(0)
- else
- code = "function (ev) {"
- for i=0 to uB
- code = code & "(" & handlers(i) & ")(ev);"
- next
- code = code & "}"
- end if
- else
- code = handlers
- end if
- ' Using @@ at the beggining to signal JSON that we don't want this quoted.
- configON.Add eventName, "@@" & code
- next
- ' set mergedConfig.Item("on") = configOn
- end if
- set configSettings = mergedConfig
- end function
- ''
- ' Returns a copy of a scripting.dictionary object
- '
- private function cloneDictionary( base )
- dim newOne, tmpKey
- Set newOne = CreateObject("Scripting.Dictionary")
- for each tmpKey in base
- newOne.Add tmpKey , base( tmpKey )
- next
- set cloneDictionary = newOne
- end function
- ''
- ' Combines two scripting.dictionary objects
- ' The base object isn't modified, and extra gets all the properties in base
- '
- private function mergeDictionary(base, extra)
- dim newOne, tmpKey
- for each tmpKey in base
- if not(extra.Exists( tmpKey )) then
- extra.Add tmpKey, base( tmpKey )
- end if
- next
- set mergeDictionary = extra
- end function
- ''
- ' Return global event handlers.
- '
- private function returnGlobalEvents()
- dim out, eventName, handlers
- dim handlersForEvent, handler, code, i
- out = ""
- if (isempty(CKEDITOR_returnedEvents)) then
- set CKEDITOR_returnedEvents = CreateObject("Scripting.Dictionary")
- end if
- for each eventName in oGlobalEvents
- handlers = oGlobalEvents( eventName )
- if not(CKEDITOR_returnedEvents.Exists(eventName)) then
- CKEDITOR_returnedEvents.Add eventName, CreateObject("Scripting.Dictionary")
- end if
- set handlersForEvent = CKEDITOR_returnedEvents.Item( eventName )
- ' handlersForEvent is another dictionary
- ' and handlers is an array
- for i = 0 to ubound(handlers)
- code = handlers( i )
- ' Return only new events
- if not(handlersForEvent.Exists( code )) then
- if (out <> "") then out = out & vbcrlf
- out = out & "CKEDITOR.on('" & eventName & "', " & code & ");"
- handlersForEvent.Add code, code
- end if
- next
- next
- returnGlobalEvents = out
- end function
- ''
- ' Initializes CKEditor (executed only once).
- '
- private function init()
- dim out, args, path, extraCode, file
- out = ""
- if (CKEDITOR_initComplete) then
- init = ""
- exit function
- end if
- if (initialized) then
- CKEDITOR_initComplete = true
- init = ""
- exit function
- end if
- args = ""
- path = ckeditorPath()
- if (timestamp <> "") and (timestamp <> "%" & "TIMESTAMP%") then
- args = "?t=" & timestamp
- end if
- ' Skip relative paths...
- if (instr(path, "..") <> 0) then
- out = out & script("window.CKEDITOR_BASEPATH='" & path & "';")
- end if
- out = out & "<scr" & "ipt type=""text/javascript"" src=""" & path & ckeditorFileName() & args & """></scr" & "ipt>" & vbcrlf
- extraCode = ""
- if (timestamp <> mTimeStamp) then
- extraCode = extraCode & "CKEDITOR.timestamp = '" & timestamp & "';"
- end if
- if (extraCode <> "") then
- out = out & script(extraCode)
- end if
- CKEDITOR_initComplete = true
- initialized = true
- init = out
- end function
- private function ckeditorFileName()
- ckeditorFileName = "ckeditor.js"
- end function
- ''
- ' Return path to ckeditor.js.
- '
- private function ckeditorPath()
- if (basePath <> "") then
- ckeditorPath = basePath
- else
- ' In classic ASP we can't get the location of this included script
- ckeditorPath = "/ckeditor/"
- end if
- ' Try to check if that folder contains the CKEditor files:
- ' If it's a full URL avoid checking it as it might point to an external server.
- if (instr(ckeditorPath, "://") <> 0) then exit function
- dim filename, oFSO, exists
- filename = server.mapPath(basePath & ckeditorFileName())
- set oFSO = Server.CreateObject("Scripting.FileSystemObject")
- exists = oFSO.FileExists(filename)
- set oFSO = nothing
- if not(exists) then
- response.clear
- response.write "<h1>CKEditor path validation failed</h1>"
- response.write "<p>The path "" & ckeditorPath & "" doesn't include the CKEditor main file (" & ckeditorFileName() & ")</p>"
- response.write "<p>Please, verify that you have set it correctly and/or adjust the 'basePath' property</p>"
- response.write "<p>Checked for physical file: "" & filename & ""</p>"
- response.end
- end if
- end function
- End Class
- ' URL: http://www.webdevbros.net/2007/04/26/generate-json-from-asp-datatypes/
- '**************************************************************************************************************
- '' @CLASSTITLE: JSON
- '' @CREATOR: Michal Gabrukiewicz (gabru at grafix.at), Michael Rebec
- '' @CONTRIBUTORS: - Cliff Pruitt (opensource at crayoncowboy.com)
- '' - Sylvain Lafontaine
- '' - Jef Housein
- '' - Jeremy Brown
- '' @CREATEDON: 2007-04-26 12:46
- '' @CDESCRIPTION: Comes up with functionality for JSON (http://json.org) to use within ASP.
- '' Correct escaping of characters, generating JSON Grammer out of ASP datatypes and structures
- '' Some examples (all use the <em>toJSON()</em> method but as it is the class' default method it can be left out):
- '' <code>
- '' <%
- '' 'simple number
- '' output = (new JSON)("myNum", 2, false)
- '' 'generates {"myNum": 2}
- ''
- '' 'array with different datatypes
- '' output = (new JSON)("anArray", array(2, "x", null), true)
- '' 'generates "anArray": [2, "x", null]
- '' '(note: the last parameter was true, thus no surrounding brackets in the result)
- '' % >
- '' </code>
- '' @REQUIRES: -
- '' @OPTIONEXPLICIT: yes
- '' @VERSION: 1.5.1
- '**************************************************************************************************************
- class JSON
- 'private members
- private output, innerCall
- '**********************************************************************************************************
- '* constructor
- '**********************************************************************************************************
- public sub class_initialize()
- newGeneration()
- end sub
- '******************************************************************************************
- '' @SDESCRIPTION: STATIC! takes a given string and makes it JSON valid
- '' @DESCRIPTION: all characters which needs to be escaped are beeing replaced by their
- '' unicode representation according to the
- '' RFC4627#2.5 - http://www.ietf.org/rfc/rfc4627.txt?number=4627
- '' @PARAM: val [string]: value which should be escaped
- '' @RETURN: [string] JSON valid string
- '******************************************************************************************
- public function escape(val)
- dim cDoubleQuote, cRevSolidus, cSolidus
- cDoubleQuote = &h22
- cRevSolidus = &h5C
- cSolidus = &h2F
- dim i, currentDigit
- for i = 1 to (len(val))
- currentDigit = mid(val, i, 1)
- if ascw(currentDigit) > &h00 and ascw(currentDigit) < &h1F then
- currentDigit = escapequence(currentDigit)
- elseif ascw(currentDigit) >= &hC280 and ascw(currentDigit) <= &hC2BF then
- currentDigit = "\u00" + right(padLeft(hex(ascw(currentDigit) - &hC200), 2, 0), 2)
- elseif ascw(currentDigit) >= &hC380 and ascw(currentDigit) <= &hC3BF then
- currentDigit = "\u00" + right(padLeft(hex(ascw(currentDigit) - &hC2C0), 2, 0), 2)
- else
- select case ascw(currentDigit)
- case cDoubleQuote: currentDigit = escapequence(currentDigit)
- case cRevSolidus: currentDigit = escapequence(currentDigit)
- case cSolidus: currentDigit = escapequence(currentDigit)
- end select
- end if
- escape = escape & currentDigit
- next
- end function
- '******************************************************************************************************************
- '' @SDESCRIPTION: generates a representation of a name value pair in JSON grammer
- '' @DESCRIPTION: It generates a name value pair which is represented as <em>{"name": value}</em> in JSON.
- '' the generation is fully recursive. Thus the value can also be a complex datatype (array in dictionary, etc.) e.g.
- '' <code>
- '' <%
- '' set j = new JSON
- '' j.toJSON "n", array(RS, dict, false), false
- '' j.toJSON "n", array(array(), 2, true), false
- '' % >
- '' </code>
- '' @PARAM: name [string]: name of the value (accessible with javascript afterwards). leave empty to get just the value
- '' @PARAM: val [variant], [int], [float], [array], [object], [dictionary]: value which needs
- '' to be generated. Conversation of the data types is as follows:<br>
- '' - <strong>ASP datatype -> JavaScript datatype</strong>
- '' - NOTHING, NULL -> null
- '' - INT, DOUBLE -> number
- '' - STRING -> string
- '' - BOOLEAN -> bool
- '' - ARRAY -> array
- '' - DICTIONARY -> Represents it as name value pairs. Each key is accessible as property afterwards. json will look like <code>"name": {"key1": "some value", "key2": "other value"}</code>
- '' - <em>multidimensional array</em> -> Generates a 1-dimensional array (flat) with all values of the multidimensional array
- '' - <em>request</em> object -> every property and collection (cookies, form, querystring, etc) of the asp request object is exposed as an item of a dictionary. Property names are <strong>lowercase</strong>. e.g. <em>servervariables</em>.
- '' - OBJECT -> name of the type (if unknown type) or all its properties (if class implements <em>reflect()</em> method)
- '' Implement a <strong>reflect()</strong> function if you want your custom classes to be recognized. The function must return
- '' a dictionary where the key holds the property name and the value its value. Example of a reflect function within a User class which has firstname and lastname properties
- '' <code>
- '' <%
- '' function reflect()
- '' . set reflect = server.createObject("scripting.dictionary")
- '' . reflect.add "firstname", firstname
- '' . reflect.add "lastname", lastname
- '' end function
- '' % >
- '' </code>
- '' Example of how to generate a JSON representation of the asp request object and access the <em>HTTP_HOST</em> server variable in JavaScript:
- '' <code>
- '' <script>alert(<%= (new JSON)(empty, request, false) % >.servervariables.HTTP_HOST);</script>
- '' </code>
- '' @PARAM: nested [bool]: indicates if the name value pair is already nested within another? if yes then the <em>{}</em> are left out.
- '' @RETURN: [string] returns a JSON representation of the given name value pair
- '******************************************************************************************************************
- public default function toJSON(name, val, nested)
- if not nested and not isEmpty(name) then write("{")
- if not isEmpty(name) then write("""" & escape(name) & """: ")
- generateValue(val)
- if not nested and not isEmpty(name) then write("}")
- toJSON = output
- if innerCall = 0 then newGeneration()
- end function
- '******************************************************************************************************************
- '* generate
- '******************************************************************************************************************
- private function generateValue(val)
- if isNull(val) then
- write("null")
- elseif isArray(val) then
- generateArray(val)
- elseif isObject(val) then
- dim tName : tName = typename(val)
- if val is nothing then
- write("null")
- elseif tName = "Dictionary" or tName = "IRequestDictionary" then
- generateDictionary(val)
- elseif tName = "IRequest" then
- set req = server.createObject("scripting.dictionary")
- req.add "clientcertificate", val.ClientCertificate
- req.add "cookies", val.cookies
- req.add "form", val.form
- req.add "querystring", val.queryString
- req.add "servervariables", val.serverVariables
- req.add "totalbytes", val.totalBytes
- generateDictionary(req)
- elseif tName = "IStringList" then
- if val.count = 1 then
- toJSON empty, val(1), true
- else
- generateArray(val)
- end if
- else
- generateObject(val)
- end if
- else
- 'bool
- dim varTyp
- varTyp = varType(val)
- if varTyp = 11 then
- if val then write("true") else write("false")
- 'int, long, byte
- elseif varTyp = 2 or varTyp = 3 or varTyp = 17 or varTyp = 19 then
- write(cLng(val))
- 'single, double, currency
- elseif varTyp = 4 or varTyp = 5 or varTyp = 6 or varTyp = 14 then
- write(replace(cDbl(val), ",", "."))
- else
- ' Using @@ at the beggining to signal JSON that we don't want this quoted.
- if left(val, 2) = "@@" then
- write( mid( val, 3 ) )
- else
- write("""" & escape(val & "") & """")
- end if
- end if
- end if
- generateValue = output
- end function
- '******************************************************************************************************************
- '* generateArray
- '******************************************************************************************************************
- private sub generateArray(val)
- dim item, i
- write("[")
- i = 0
- 'the for each allows us to support also multi dimensional arrays
- for each item in val
- if i > 0 then write(",")
- generateValue(item)
- i = i + 1
- next
- write("]")
- end sub
- '******************************************************************************************************************
- '* generateDictionary
- '******************************************************************************************************************
- private sub generateDictionary(val)
- innerCall = innerCall + 1
- if val.count = 0 then
- toJSON empty, null, true
- exit sub
- end if
- dim key, i
- write("{")
- i = 0
- for each key in val
- if i > 0 then write(",")
- toJSON key, val(key), true
- i = i + 1
- next
- write("}")
- innerCall = innerCall - 1
- end sub
- '******************************************************************************************************************
- '* generateObject
- '******************************************************************************************************************
- private sub generateObject(val)
- dim props
- on error resume next
- set props = val.reflect()
- if err = 0 then
- on error goto 0
- innerCall = innerCall + 1
- toJSON empty, props, true
- innerCall = innerCall - 1
- else
- on error goto 0
- write("""" & escape(typename(val)) & """")
- end if
- end sub
- '******************************************************************************************************************
- '* newGeneration
- '******************************************************************************************************************
- private sub newGeneration()
- output = empty
- innerCall = 0
- end sub
- '******************************************************************************************
- '* JsonEscapeSquence
- '******************************************************************************************
- private function escapequence(digit)
- escapequence = "\u00" + right(padLeft(hex(ascw(digit)), 2, 0), 2)
- end function
- '******************************************************************************************
- '* padLeft
- '******************************************************************************************
- private function padLeft(value, totalLength, paddingChar)
- padLeft = right(clone(paddingChar, totalLength) & value, totalLength)
- end function
- '******************************************************************************************
- '* clone
- '******************************************************************************************
- private function clone(byVal str, n)
- dim i
- for i = 1 to n : clone = clone & str : next
- end function
- '******************************************************************************************
- '* write
- '******************************************************************************************
- private sub write(val)
- output = output & val
- end sub
- end class
- %>
|