cml 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +18 -0
- data/Rakefile +56 -0
- data/VERSION +1 -0
- data/cml.gemspec +129 -0
- data/lib/cml/converters/jsawesome.rb +103 -0
- data/lib/cml/gold.rb +33 -0
- data/lib/cml/liquid_filters.rb +13 -0
- data/lib/cml/parser.rb +160 -0
- data/lib/cml/tag.rb +308 -0
- data/lib/cml/tags/checkbox.rb +77 -0
- data/lib/cml/tags/checkboxes.rb +38 -0
- data/lib/cml/tags/group.rb +25 -0
- data/lib/cml/tags/hidden.rb +17 -0
- data/lib/cml/tags/iterate.rb +86 -0
- data/lib/cml/tags/meta.rb +12 -0
- data/lib/cml/tags/multiple_text.rb +11 -0
- data/lib/cml/tags/option.rb +29 -0
- data/lib/cml/tags/radio.rb +48 -0
- data/lib/cml/tags/radios.rb +36 -0
- data/lib/cml/tags/ratings.rb +61 -0
- data/lib/cml/tags/search.rb +97 -0
- data/lib/cml/tags/select.rb +50 -0
- data/lib/cml/tags/text.rb +45 -0
- data/lib/cml/tags/textarea.rb +45 -0
- data/lib/cml/tags/thumb.rb +25 -0
- data/lib/cml/tags/unknown.rb +21 -0
- data/lib/cml.rb +15 -0
- data/spec/complex_spec.rb +127 -0
- data/spec/converters/jsawesome_spec.rb +75 -0
- data/spec/fixtures/complex.cml +23 -0
- data/spec/fixtures/html.cml +34 -0
- data/spec/fixtures/invalid.cml +10 -0
- data/spec/fixtures/script-style.cml +12 -0
- data/spec/fixtures/segfault.cml +1 -0
- data/spec/gold_spec.rb +29 -0
- data/spec/meta_spec.rb +47 -0
- data/spec/normalize_spec.rb +214 -0
- data/spec/show_data_spec.rb +308 -0
- data/spec/sorta_match.rb +41 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/tags/checkbox_spec.rb +155 -0
- data/spec/tags/checkboxes_spec.rb +171 -0
- data/spec/tags/group_spec.rb +108 -0
- data/spec/tags/hidden_spec.rb +17 -0
- data/spec/tags/iterate_spec.rb +259 -0
- data/spec/tags/meta_spec.rb +14 -0
- data/spec/tags/multiple_text_spec.rb +40 -0
- data/spec/tags/radios_spec.rb +81 -0
- data/spec/tags/ratings_spec.rb +79 -0
- data/spec/tags/search_spec.rb +132 -0
- data/spec/tags/select_spec.rb +76 -0
- data/spec/tags/tag_spec.rb +93 -0
- data/spec/tags/text_spec.rb +66 -0
- data/spec/tags/textarea_spec.rb +58 -0
- data/spec/tags/thumb_spec.rb +20 -0
- data/spec/tags/unknown_spec.rb +19 -0
- data/spec/validation_spec.rb +62 -0
- metadata +182 -0
@@ -0,0 +1 @@
|
|
1
|
+
<script type="text/javascript" src="http://api.maps.yahoo.com/ajaxymap?v=3.8&appid=Knx84fDV34H2VnhVU1DoD7chT1wjJ2r36uf4dZW7Vc5si9sqQRAYU_g8fo7zV.wF"></script><br><script src="/javascripts/upload.js" type="text/javascript" charset="utf-8"></script><br><script type="text/javascript"><br> mapInterface=new Object();//Wrapper for all info we will store;<br> mapInterface.baseCrowdflowerUrl='http://crowdflower.com';//'http://www.crowdflower.com';<br> mapInterface.debug=false;<br> mapInterface.jobId=1059;<br> mapInterface.accepted=new Object();<br> mapInterface.accepted.unit=null;<br> mapInterface.accepted.unitId=null;<br> mapInterface.accepted.cart=new Object();//Contains all units selected<br> //Consider using cookie for this<br> mapInterface.accepted.cond=false; //Bool thatrepresents whether the user has accepted a task yet<br> mapInterface.imageBaseUrl='http://a1.doloreslabs.com/q82/images/';<br> mapInterface.startingZoom=15;<br> mapInterface.addressZoom=10;<br> mapInterface.searchBox=new Object();<br> mapInterface.searchBox.lonRange=10;<br> mapInterface.searchBox.latRange=10;<br> mapInterface.maxDistance=160900;//100 miles in meters<br> mapInterface.maxPoints=300; //Max points to display on the screen<br> mapInterface.formAwesome=new Object(); <br> mapInterface.formAwesome.form = [["*the_specified_location",["yes","no"]],["#and_the_situation","For example, \"This is a new road and there is no paint.\""],["#specified_latitudelongitude_location",""],["*the_road_paved",["yes","no"]],["*road_private_access",["yes","no"]],["*road_one_way",["yes","no"]],["*on_the_road",["yes","no"]],["in_the_map",""],["in_the_map_2",""],["of_the_road",""],["the_new_road",""],["of_the_map",""],["#residential_development_etc","For example, \"This is a new road in a developing neighborhood.\""],["*in_the_future",["yes","no"]],["#please_elaborate",""],["#about_the_task",""]];<br> mapInterface.formAwesome.labels={"in_the_map_2":{"label":"What is the number of lanes in the south or west-ward direction of travel in the map? ","required":true},"of_the_road":{"label":"What is the speed limit on the initial section of the road? ","required":true},"the_road_paved":{"label":"Is the road paved? ","required":true},"road_one_way":{"label":"Is the road one way? ","required":true},"about_the_task":{"label":"Any comments about the task?"},"the_new_road":{"label":"Are there any turn restrictions turning on to the new road, or turning off the new road? ","required":true},"the_specified_location":{"label":"Does a road exist at the specified location? ","required":true},"on_the_road":{"label":"Is there a divider on the road? ","required":true},"and_the_situation":{"label":"Describe the road and the situation. ","required":true},"road_private_access":{"label":"Is the road private access? ","required":true},"in_the_map":{"label":"What is the number of lanes in the north or east-ward direction of travel in the map? ","required":true},"of_the_map":{"label":"What are the minimum and maximum address numbers on the road within the range of the map? ","required":true},"residential_development_etc":{"label":"Please provide a general description of the road and area. Note whether the road is still under construction, leads to hotels, if it is in the residential development, etc. ","required":true},"in_the_future":{"label":"Would you be willing to do this task again in the future?","required":true},"please_elaborate":{"label":"Please elaborate"},"specified_latitudelongitude_location":{"label":"If the road did not exist at the specified latitude/longitude location but was nearby, please describe its actual location. What was at the specified latitude/longitude location?"}};<br> <br> mapInterface.points=new Object();<br> //mapInterface.points.data=<?=file_get_contents('units.json')?>;<br> <br> //Returns an array of units that fit in the appropriate location<br> mapInterface.points.filterByLoc=function(userLoc){<br> var filtUnits=new Array();<br> var counter=0;<br> for(var unitId in mapInterface.points.data){<br> var unit=mapInterface.points.data[unitId];<br> //Check distance<br> if( great_circle_distance(userLoc,unit)>=mapInterface.maxDistance){<br> continue;<br> }<br> else if(counter >= mapInterface.maxPoints){<br> break;<br> }<br> else{<br> filtUnits[unitId]=unit;<br> counter++;<br> }<br> }<br> //*/<br> return filtUnits;<br> <br> //Calculates Euclidean distance between two points<br> function checkDistance(point1,point2){<br> return Math.pow (<br> Math.pow( (point2.Lat-point1.Lat), 2)+Math.pow( (point2.Lon-point1.Lon), 2)<br> , .5);<br> }<br> //Gabe smed's true distance calc<br> function great_circle_distance(point_a, point_b) {<br> var lat1 = point_a.Lat;<br> var lat2 = point_b.Lat;<br> var lon1 = point_a.Lon;<br> var lon2 = point_b.Lon;<br> <br> var R = 6378140; // meters<br> var dLat = deg_to_rad(lat2-lat1)<br> var dLon = deg_to_rad(lon2-lon1)<br> var a = Math.sin(dLat/2) * Math.sin(dLat/2) +<br> Math.cos(deg_to_rad(lat1)) * Math.cos(deg_to_rad(lat2)) *<br> Math.sin(dLon/2) * Math.sin(dLon/2);<br> var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));<br> var d = R * c;<br> <br> return d<br> <br> function deg_to_rad(deg) {<br> return deg * Math.PI / 180.0<br> }<br> }<br> <br> };<br> mapInterface.points.draw=function(userLoc, map){<br> //AJAX GET request to pull units in a large bounding box<br> //Then we use method .filterByLoc to reduce the search further<br> //(function(){<br> var dataRequest=new Request.JSON({<br> url: mapInterface.baseCrowdflowerUrl+'/jobs/'+mapInterface.jobId+'/units/custom.json',<br> onSuccess: function(responseJSON, responseText){<br> //console.log(responseJSON);<br> mapInterface.points.data=new Object();<br> for(var unitId in responseJSON){<br> mapInterface.points.data[unitId]= mapInterface.formatUnit(responseJSON[unitId], unitId);<br> }<br> afterDataUpdated();<br> $$('div.loading').setStyle('visibility','hidden');<br> },<br> onFailure: function(xhr){<br> alert('Error loading data. Please try refreshing the page or send an email to info@doloreslabs.com');<br> }<br> });<br> var searchBoxLonSize=mapInterface.searchBox.lonRange;<br> var searchBoxLatSize=mapInterface.searchBox.latRange;<br> var params={ c1_key:'long'<br> ,c1_val: (userLoc.Lon-searchBoxLonSize).toString()+','+(userLoc.Lon+searchBoxLonSize).toString()<br> ,c1_op: 'bt'<br> ,c2_key:'lat'<br> ,c2_val: (userLoc.Lat-searchBoxLatSize).toString()+','+(userLoc.Lat+searchBoxLatSize).toString()<br> ,c2_op: 'bt'<br> };<br> dataRequest.get(params);<br> //})();<br> function afterDataUpdated(){<br> map.removeMarkersAll();<br> if(typeof(userLoc)=='undefined'){<br> return false;<br> }<br> var units=mapInterface.points.filterByLoc(userLoc);<br> if ( units.length===0){<br> alert('Sorry, no results found! Try another address.');<br> return false;<br> }<br> for(var unitId in units){<br> unit=units[unitId];<br> if(typeof(unit['file1'])=='undefined'<br> || typeof(unit['file2'])=='undefined'){<br> //For some reason some of the unit objects are malformed<br> //console.log(unit);<br> continue;<br> }<br> <br> var sMarker=new YMarker(new YGeoPoint( unit.Lat,unit.Lon ));<br> sMarker.unitId=unitId;<br> sMarker.unit=unit;<br> //Add onclick event to the markers<br> YEvent.Capture(sMarker,EventsList.MouseClick,function(e){<br> if(mapInterface.accepted.cond===true){<br> mapInterface.popup.confirmReturnUnit.bind(this, [this.unit, this.unitId])();<br> }<br> else{<br> mapInterface.popup.simpleUnit.bind(this, [this.unit, this.unitId])();<br> }<br> });<br> map.addOverlay(sMarker);<br> }<br> }<br> };//*/<br> //Adds some custom properties to the unit<br> mapInterface.formatUnit=function(unit, unitId){<br> unit.Lat=unit.lat;<br> unit.Lon=unit.long;<br> unit.image1Url=mapInterface.imageBaseUrl+unit.file1.trim();<br> unit.image2Url=mapInterface.imageBaseUrl+unit.file2.trim();<br> unit.unitMapLink="<a href=\"http://maps.yahoo.com/#mvt=m&lat="+unit.Lat+"&lon="+unit.Lon+"&zoom=14&q1="+unit.Lat+"%252C%2520"+unit.Lon+"\" target=\"_blank\">Click here to get driving instructions</a>";<br> unit.img1html='<a target="_blank" href="'+unit.image1Url+'"><img src="'+unit.image1Url+'"/></a>';<br> unit.img2html='<a target="_blank" href="'+unit.image2Url+'"><img src="'+unit.image2Url+'"/></a>';<br> unit.unitId=unitId;<br> return unit;<br> }<br> <br> mapInterface.popup=new Object();<br> //Used for callback on click of a YAHOO map marker.<br> //Pops up a new window with a simple unit view <br> mapInterface.popup.simpleUnit=function(unit, unitId){<br> //Kill any existing window div<br> $$('div.popup').dispose();<br> //Create a new popup div window (popup) using template found in div.popupContent<br> var divText=$(document.body)<br> .getElement('div.popupContent div.simpleUnitView')<br> .get('html')<br> .substitute(unit);<br> <br> //Inject into DOM<br> var newDiv=new Element('div', {"class": "popup", "id":"popupU"})<br> .set('html',divText)<br> .inject( $(document.body) )<br> .store('unit',unit)<br> .store('unitId',unitId);<br> <br> //Wire up close button<br> newDiv.getElement('span.close').addEvent('click',function(e){<br> this.getParent().getParent().dispose();<br> });<br> <br> <br> //Wire up accept button<br> if(mapInterface.previewMode===true){<br> newDiv.getElement('div.viewMore').dispose();<br> $$('div.simpleUnitView div.previewInstructions').setStyle('display','block');<br> }<br> else{<br> //Wire up "View More Details" button<br> newDiv.getElement('div.viewMore').addEvent('click',mapInterface.popup.advUnit);<br> }<br> <br> //Make div popup and transparent while dragging<br> var movableDiv=new Drag.Move(newDiv,{<br> onStart:function(el){el.addClass('dragging').set('opacity','.5');},<br> onComplete: function(el){el.removeClass('dragging').set('opacity','1.0');} <br> });<br> };<br> //Used as callback for when someone clicks "View more info" on the unit popup div<br> //Fullscreens an existing unit<br> mapInterface.popup.advUnit=function(e){<br> //Move window to upper left, Add a class that will include styles to maximize div to full screen<br> var popupDiv=this.getParent().position({x:'left',y:'top'}).addClass('fullscreen');<br> var unitId=this.getParent().retrieve('unitId');<br> var unit=this.getParent().retrieve('unit');<br> <br> var divText=$(document.body)<br> .getElement('div.popupContent div.advUnitView')<br> .get('html')<br> .substitute(unit);<br> this.getParent().set('html',divText);<br> <br> popupDiv.getElement('div.accept').addEvent('click',function(e){<br> //Lock in unit through AJAX request<br> var acceptRequest=new Request.JSON({<br> url:'/jobs/'+mapInterface.jobId+'/units/'+unitId+'/custom',<br> method: 'put',<br> data: {unit:{state:'judging'}},<br> onSuccess: function(responseJSON, responseText){<br> mapInterface.accepted.unitId=unitId;<br> mapInterface.accepted.unit=unit;<br> mapInterface.accepted.cond=true;<br> mapInterface.popup.printableForm.bind( this )();<br> $$('div.acceptedTaskLink').setStyle('display','block');<br> }.bind(this.getParent().getParent()),<br> onFailure: function(){<br> alert('Sorry, it seems a network problem is preventing you from accepting the task. Please try again later or email admin@doloreslabs.com');<br> }<br> });<br> //Params<br> acceptRequest.send();<br> });<br> //Wire up close button<br> popupDiv.getElement('span.close').addEvent('click',function(e){<br> this.getParent().getParent().dispose();<br> });<br> };<br> //Pops up a new window at the beginning of task<br> mapInterface.popup.splash=function(){<br> var content=$(document.body).getElement('div.popupContent div.splash').get('html');<br> var newDiv=new Element('div', {"class": "splash popup fullscreen"})<br> .set('html',content)<br> .inject( $(document.body) );<br> //Wire up close button<br> newDiv.getElement('span.close').addEvent('click',function(e){<br> this.getParent().getParent().dispose();<br> });<br> //Wire up returning button<br> newDiv.getElement('div.returning').addEvent('click',function(e){<br> mapInterface.popup.checkUnitId(); <br> });<br> //Wire up new button<br> newDiv.getElement('div.new').addEvent('click',function(e){<br> this.getParent().getParent().dispose();<br> });<br> };<br> <br> //Pops up a new window at the beginning of task<br> mapInterface.popup.preview=function(){<br> var content=$(document.body).getElement('div.popupContent div.preview').get('html');<br> var newDiv=new Element('div', {"class": "preview popup"})<br> .set('html',content)<br> .inject( $(document.body) );<br> //Wire up close button<br> newDiv.getElement('span.close').addEvent('click',function(e){<br> newDiv.dispose();<br> });<br> //Wire up returning button<br> newDiv.getElement('div.preview.clickable').addEvent('click',function(e){<br> //Undisable search box (which is by default disabled in PREVIEW mode)<br> if(mapInterface.previewMode===true){<br> $('userAddress').set('disabled',false);<br> }<br> newDiv.dispose();<br> });<br> <br> //Make div popup and transparent while dragging<br> var movableDiv=new Drag.Move(newDiv,{<br> onStart:function(el){el.addClass('dragging').set('opacity','.5');},<br> onComplete: function(el){el.removeClass('dragging').set('opacity','1.0');} <br> });<br> };<br> <br> //Allow user to enter in existing unit id<br> mapInterface.popup.checkUnitId=function(){<br> var content=$(document.body).getElement('div.popupContent div.checkUnitId').get('html');<br> var popupDiv= new Element('div', {"class": "popup checkUnitId fullscreen"})<br> .set('html',content)<br> .inject( $(document.body) );<br> //So we can distinguish this div from the hidden one<br> popupDiv.getElement('input.unitId').addClass('real');<br> //Wire up close button<br> popupDiv.getElement('span.close').addEvent('click',function(e){<br> this.getParent().getParent().dispose();<br> });<br> //Wire up submit button <br> popupDiv.getElement('div.checkUnitId').addEvent('click',function(e){<br> //Grab unitId<br> var unitId=Number( $(document.body).getElement('input.unitId.real').value.trim() );<br> if(typeof(unitId)!='number' || !isFinite(unitId) || unitId<=0 ){<br> alert('The unit ID must be a number in the format 9999999');<br> return false;<br> }<br> var request=new Request.JSON({<br> url: mapInterface.baseCrowdflowerUrl+'/jobs/'+mapInterface.jobId+'/units/'+unitId+'/custom.json',<br> method: 'get',<br> onSuccess: function(responseText, responseXML){<br> mapInterface.accepted.unitId=unitId;<br> mapInterface.accepted.unit=mapInterface.formatUnit(responseText.data, unitId);<br> mapInterface.accepted.cond=true;<br> //console.log(responseText);<br> mapInterface.popup.submittableForm();<br> },<br> onFailure: function(xhr){<br> alert('The entered unit ID is not valid. Please ensure you entered it correctly and try again.');<br> }<br> });<br> request.send();<br> });<br> //Wire up cancel button<br> popupDiv.getElement('div.cancel').addEvent('click',function(e){<br> popupDiv.dispose(); <br> });<br> <br> //Wire up input box so that hitting enter submits form<br> popupDiv.getElement('input.unitId').addEvent('keypress',function(e){<br> if(e.key=='enter'){<br> e.stop(); //Prevent form from submitting<br> popupDiv.getElement('div.checkUnitId').fireEvent('click');<br> }<br> });<br> };<br> //Now actually display the form<br> mapInterface.popup.submittableForm=function(e){<br> //Kill existing popups<br> $$('div.popup').dispose();<br> //Grab HTML from hidden div on page<br> var html=$(document.body).getElement('div.popupContent div.submittableForm').get('html').substitute(mapInterface.accepted.unit);<br> //Create the windowed div<br> var newDiv=new Element('div', {"class": "submittableForm popup fullscreen"})<br> .set('html',html)<br> .inject( $(document.body) );<br> //Wire up close button<br> newDiv.getElement('span.close').addEvent('click',function(e){<br> this.getParent().getParent().dispose();<br> });<br> //Add form<br> var jsaDivId='u'+mapInterface.accepted.unitId;<br> var jsaDiv=new Element('div', {"class": "submittableForm", id: jsaDivId} )<br> .inject( newDiv.getElement('div.content form'), 'bottom' );<br> //JSawesome creates the form elements<br> var myJSAwesome=new JSAwesome(jsaDivId,mapInterface.formAwesome.form, mapInterface.formAwesome.labels);<br> myJSAwesome.to_html();<br> myJSAwesome.addValidation();<br> <br> //Submit button<br> var submitButton=new Element('input', {type: "submit", name: "submit", value: "Submit"}).inject(newDiv.getElement('div.content form'), 'bottom');<br> <br> //Add some validation when submitting<br> submitButton.addEvent('click',function(e){<br> if( $$('.files').length > 0 ){<br> var myCookie=Cookie.write('submittedForm','yes',{duration: 30}); //save for a month)<br> return true;<br> }<br> else{<br> e.stop();<br> alert('You didn\'t upload any files! You must upload an image of the street to submit this task. Make sure you click the "Upload Images" button to upload the files after you have selected them from your computer.');<br> }<br> });<br> <br> newDiv.getElement('input.upload').addClass('real');<br> newDiv.getElement('div.uploadStatus').addClass('real');<br> newDiv.getElement('ul.list').addClass('real');<br> newDiv.getElement('a.browse').addClass('real');<br> mapInterface.uploader.wireUp(newDiv);<br> };<br> <br> mapInterface.popup.printableForm=function(e){<br> //Kill existing popups<br> $$('div.popup').dispose();<br> //Grab HTML from hidden div on page<br> var html=$(document.body).getElement('div.popupContent div.printableForm').get('html').substitute(mapInterface.accepted.unit);<br> //Create the windowed div<br> var newDiv=new Element('div', {"class": "printableForm popup fullscreen"})<br> .set('html',html)<br> .inject( $(document.body) );<br> //Wire up close button<br> newDiv.getElement('span.close').addEvent('click',function(e){<br> this.getParent().getParent().dispose();<br> });<br> var form=new Element('form', {"class": "printableForm", id: "printableForm" } )<br> .inject( newDiv.getElement('div.content') );<br> new JSAwesome('printableForm',mapInterface.formAwesome.form, mapInterface.formAwesome.labels).to_html();<br> }<br> mapInterface.uploader=new Object();<br> mapInterface.uploader.wireUp=function(newDiv){<br> newDiv.getElement('input.upload').addEvent('click', function(){mapInterface.uploader.swiffy.upload()})<br> var unit_id = mapInterface.accepted.unitId;<br> var worker_id = "{{_worker_id}}"<br> mapInterface.uploader.swiffy = new FancyUpload2(newDiv.getElement('div.uploadStatus'), newDiv.getElement('ul.list'), {<br> url: 'http://crowdflower_upload.s3.amazonaws.com/',<br> typeFilter: {'Data (*.jpg, *.jpeg)': '*.jpg; *.jpeg'},<br> fieldName: 'file',<br> path: '/Swiff.Uploader.swf',<br> limitSize: 5 * 1024 * 1024, // 5Mb<br> multiple: true,<br> mergeData: true,<br> autoStart: false,<br> method: 'post',<br> passStatus:[201],<br> data: {<br> 'key': 'uploads/'+unit_id+'-'+worker_id+'_1.jpg',<br> 'AWSAccessKeyId': "00NZJT8HNJ5H6N5MGP02",<br> 'success_action_status' : 201,<br> 'acl': 'private',<br> 'policy': "eyJleHBpcmF0aW9uIjogIjIwMTAtMDEtMDFUMDA6MDA6MDBaIiwKICAiY29uZGl0aW9ucyI6IFsgCiAgICB7ImJ1Y2tldCI6ICJjcm93ZGZsb3dlcl91cGxvYWQifSwgCiAgICBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAidXBsb2Fkcy8iXSwKICAgIFsic3RhcnRzLXdpdGgiLCAiJEZpbGVuYW1lIiwgIiJdLAogICAgeyJhY2wiOiAicHJpdmF0ZSJ9LAogICAgWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsIDAsIDEwNDg1NzZdLAogICAgWydlcScsICckc3VjY2Vzc19hY3Rpb25fc3RhdHVzJywgJzIwMSddCiAgXQp9Cg==",<br> 'signature': "RUrMBFa13RBYm4HQ5zGfE0BXFIY=" <br> },<br> fileInvalid: function(e) {<br> flash("File must be less than 10MB", "error")<br> },<br> onComplete: function(res){<br> $$('input.upload.real').set({'value': 'Upload complete!'})<br> this.fileList.each(function(file,i){<br> if(file.element.hasClass('completed'))<br> return<br> file.element.addClass('completed').getElement('.file-remove').dispose()<br> new Element('input', {type:'hidden', 'class':'files', name:'u'+unit_id+'[_files][]', value:unit_id+'-'+worker_id+'_'+(i+1)+'.'+file.extension}).inject(this.status)<br> }, this)<br> var later = function(){<br> this.size = this.uploading = this.bytesLoaded = this.percentLoaded = 0;<br> }<br> later.delay(500,this)<br> $$('input.upload.real').set({disabled:false, value:'Upload these images', style:'display:none'})<br> },<br> onFileRemove: function(w){<br> if(this.fileList.length == 0) {<br> $$('a.browse.real').set('html', 'Choose images of the road')<br> $$('input.upload.real').setStyle('display', 'none')<br> }<br> },<br> onBeforeStart: function(){<br> $$('input.upload.real').set({'disabled':true, 'value': 'Uploading...'})<br> },<br> onSelectSuccess: function(files){<br> this.overallProgress.set(0);<br> this.currentProgress.set(0);<br> var offset = this.fileList.length - files.length + 1<br> files.each(function(f,i){<br> var data = mapInterface.uploader.swiffy.options.data<br> data.key = data.key.replace(/_(\d+)\.jpg/,'_'+(offset + i)+'.'+f.extension)<br> f.setOptions({data:data})<br> })<br> $$('a.browse.real').set('html', 'Choose more images of the road')<br> $$('input.upload.real').setStyle('display','')<br> },<br> onFail: function(error) {<br> switch (error) {<br> case 'hidden': // works after enabling the movie and clicking refresh<br> alert('To enable the embedded uploader, unblock it in your browser and refresh (see Adblock).');<br> break;<br> case 'blocked': // This no *full* fail, it works after the user clicks the button<br> alert('To enable the embedded uploader, enable the blocked Flash movie (see Flashblock).');<br> break;<br> case 'empty': // Oh oh, wrong path<br> alert('A required file was not found, please be patient and we\'ll fix this.');<br> break;<br> case 'flash': // no flash 9+ :(<br> alert('To enable the embedded uploader, install the latest Adobe Flash plugin.')<br> }<br> },<br> target: ($$('a.browse.real')[0])<br> });<br> };<br> <br> <br> <br> mapInterface.popup.confirmReturnUnit=function(unit, unitId){<br> //Kill any existing window div<br> $$('div.popup').dispose();<br> //Create a new popup div window (popup) using template found in div.popupContent<br> var divText=$(document.body)<br> .getElement('div.popupContent div.confirmReturnUnit')<br> .get('html');<br> <br> //Inject into DOM<br> var newDiv=new Element('div', {"class": "popup confirmReturnUnit"})<br> .set('html',divText)<br> .inject( $(document.body) )<br> <br> //Wire up close button<br> newDiv.getElement('span.close').addEvent('click',function(e){<br> this.getParent().getParent().dispose();<br> });<br> <br> //Wire up "View More Details" button<br> newDiv.getElement('div.confirm').addEvent('click',function(unit, unitId){<br> mapInterface.popup.simpleUnit(unit, unitId);<br> /*<br> //If task is already accepted, we need to first revoke the original task<br> if(mapInterface.accepted.cond===true){<br> //AJAX call to set state of the unit back to unjudged<br> var returnRequest=new Request.JSON({<br> url:'/jobs/'+mapInterface.jobId+'/units/'+mapInterface.accepted.unitId+'/custom',<br> method: 'put',<br> data: {unit:{state:'judgable'}},<br> onSuccess: function(responseJSON, responseText){<br> mapInterface.accepted.unitId=null;<br> mapInterface.accepted.unit=null;<br> mapInterface.accepted.cond=false;<br> $$('div.acceptedTaskLink').setStyle('display','none');<br> $$('div.popup').dispose();<br> },<br> onFailure: function(){<br> alert('Error connecting to server: could not return task. If you continue to receive this error, please send an email to admin@doloreslabs.com');<br> }<br> });<br> //Params<br> returnRequest.send();<br> }<br> //*/<br> }.bind(this, [unit, unitId]) );<br> newDiv.getElement('div.cancel').addEvent('click',function(e){<br> mapInterface.popup.printableForm(); <br> });<br> <br> //Make div popup and transparent while dragging<br> var movableDiv=new Drag.Move(newDiv,{<br> onStart:function(el){el.addClass('dragging').set('opacity','.5');},<br> onComplete: function(el){el.removeClass('dragging').set('opacity','1.0');} <br> });<br> }<br> <br> // Create a Map that will be placed in the "map" div.<br> window.addEvent('domready',function(){<br> if( Cookie.read('submittedForm') === 'yes'){<br> Cookie.write('submittedForm','no');<br> alert('Thanks for submitting the task! Now you can select a new task or submit answers to another one.');<br> }<br> <br> //Hide existing submit button<br> $$('input[type=submit]').addClass('invisible');<br> <br> //Check if this is preview in AMT or not<br> if( $$('input[type=submit]')[0].get('disabled') ){<br> mapInterface.previewMode=true;<br> $$('div.linkToSubmitPage.clickable').setStyle('visibility','hidden');<br> mapInterface.popup.preview();<br> }<br> //Only display splash screen if we're not in preview mode<br> else{<br> mapInterface.previewMode=false;<br> mapInterface.popup.splash();<br> }<br> <br> var map = new YMap($('map')); <br> // Add the ability to change between Sat, Hybrid, and Regular Maps<br> map.addTypeControl(); <br> // Add the zoom control. Long specifies a Slider versus a "+" and "-" zoom control<br> map.addZoomLong(); <br> // Add the Pan control to have North, South, East and West directional control<br> map.addPanControl(); <br> // Specifying the Map starting location and zoom level<br> map.drawZoomAndCenter("San Francisco", mapInterface.startingZoom);<br> <br> $$('div.acceptedTaskLink').addEvent('click',function(){<br> mapInterface.popup.printableForm();<br> });<br> <br> //Wire up the user address submit button<br> $$('span#submitUserForm').addEvent('click',function(){<br> $$('div.loading').setStyle('visibility','visible');<br> var userAddress=$('userAddress').value;<br> map.geoCodeAddress(userAddress);<br> YEvent.Capture(map, EventsList.onEndGeoCode, function(geoCode) {<br> map.drawZoomAndCenter(geoCode.GeoPoint,mapInterface.addressZoom);<br> if (geoCode.success){<br> //Clear points<br> mapInterface.points.draw(geoCode.GeoPoint,map);<br> }<br> });<br> });<br> <br> //Wire up take me back to home page link<br> $$('div.linkToSubmitPage').addEvent('click',function(){<br> mapInterface.popup.checkUnitId();<br> });<br> <br> //Change default action of hitting enter on the input element<br> $$('input#userAddress').addEvent('keypress',function(e){<br> if(e.key=='enter'){<br> e.stop(); //Prevent form from submitting<br> $$('span#submitUserForm').fireEvent('click');<br> }<br> });<br> });<br></script><br><style type="text/css"><br>.invisible{<br> display:none;<br>}<br>input{<br> margin-right:15px;<br>}<br>div#map{<br> <br> height:400px;<br> width:700px;<br>}<br>div.loading{<br> background-color:yellow;<br> width:8em;<br> font-size:130%;<br> visibility:hidden;<br>}<br>div.loadingTop{<br> position:fixed;<br> left:0px;<br> top:0px;<br> z-index:1000;<br> background-color:yellow;<br> width:8em;<br> font-size:130%;<br> display:none;<br>}<br>div.acceptedTaskLink{<br> margin-top:5px;<br> display:none;<br> <br>}<br>div.userLocation{<br> padding-top:30px;<br>}<br>span#submitUserForm{<br> cursor:pointer;<br> background-color:#5D9732;<br> padding:4px;<br> color:white;<br>}<br>input#userAddress{<br> width:50em;<br>}<br>/*Styling for div/span buttons*/<br>div.clickable{<br> background-color:#27572A;<br> padding:5px;<br> cursor:pointer;<br> text-align:center;<br> font-size:120%;<br> color:white;<br>}<br>div.clickable.small{<br> width:10em;<br>}<br>div.popup{<br> background-color:white;<br> border-width:5px;<br> border-style:solid;<br> border-color:black;<br> width:400px;<br> z-index:255;<br> position:fixed;<br> top:10%;<br> left:10%;<br> cursor:-moz-grab;<br> cursor:grab;<br>}<br>div.popup.preview{<br> width:540px;<br>}<br>div.dragging{<br> cursor:-moz-grabbing;<br> cursor:grabbing;<br>}<br>div.popup.fullscreen{<br> width:96%;<br> height:96%;<br> position:absolute;<br> left:2px;<br> top:2px;<br>}<br>div.popup div.topBar{<br> width:100%;<br> text-align:right;<br> background-color:#5D9732;<br>}<br>div.popup.fullscreen{<br> cursor:default;<br>}<br>/*Close button*/<br>div.popup span.popupButton{<br> padding-left:5px;<br> padding-right:5px;<br> background-color:black;<br> color:white;<br> cursor:pointer;<br>}<br>div.popup span.popupButtonSpacer{<br> background-color:inherit;<br> padding:0px;<br> padding-left:3px;<br>}<br>div.popup div.content{<br> background-color:white;<br> padding:20px;<br>}<br>div.popup div.content div.image1{<br> width:300px;<br>}<br>div.popup div.content div.image2{<br> width:300px;<br>}<br>div.popup.fullscreen div.content div.imageHolder{<br> float:right;<br> width:60%;<br>}<br>div.popup.fullscreen div.content div.image1{<br> height:40%;<br> float:right;<br>}<br>div.popup.fullscreen div.content div.image2{<br> height:40%;<br> float:right;<br>}<br>div.popup.fullscreen div.text{<br> padding:40px;<br>}<br>div.popup div.content img{<br> width:100%;<br>}<br>div.popupContent{<br> display:none;<br>}<br>div.popup.splash{<br> cursor:default;<br> position:fixed;<br> top:2px;<br> left:2px;<br> bottom:2px;<br> right:2px;<br>}<br>div.popup.splash div.returning{<br> width:60%;<br> margin-top:20%;<br> margin-left:15%;<br>}<br>div.popup.splash div.new{<br> margin-top:1em;<br> margin-left:15%;<br> width:60%;<br>}<br>div.popup.checkUnitId input{<br> width:10em;<br> margin-top:5%;<br> margin-bottom:5px;<br>}<br>div#formAwesome{<br> width:95%;<br> height:95%;<br> margin-top:5%;<br>}<br>div.linkToSubmitPage{<br> margin-top:3px;<br> width:45em;<br> font-size:80%;<br>}<br>div.popup.fullscreen.printableForm{<br> height:auto;<br> cursor:default;<br>}<br>div.popup.fullscreen.submittableForm{<br> height:auto;<br> cursor:default;<br>}<br>div.popup div.previewInstructions{<br> display:none;<br> padding:10px;<br>}<br>div.vertPadding{<br> margin-top:5px;<br>}<br></style><br><style type="text/css" media="screen"><br>/*Uploader styles*/<br>div.uploader{<br> margin-left:10px;<br> width:auto;<br>}<br>div.uploader img{<br> width:auto !important;<br>}<br>div#status{<br> display:hidden;<br>}<br>.progress {<br> background: white url(/images/progress-bar/progress.gif) no-repeat +50% 0;<br> margin-right: 0.5em;<br>}<br>.progress-text{<br> font-size: 0.9em;<br> font-weight: bold;<br>}<br>.file-remove {<br> font-size:0.9em;<br> padding:5px;<br> color:#ad1a2c;<br>}<br>.file-info {<br> margin-left:8px;<br>}<br>.file-name {<br> margin-left:5px;<br>}<br>.completed {<br> color:#CCC;<br>}<br></style><br><div class="loadingTop">Loading</div><br><div class="linkToSubmitPage clickable"><br> I've already driven to a location and completed a task. Let me submit my answers!<br></div><br><div class="userLocation"><br> <form name="userLocationForm"><br> <h3>Enter your city to find nearby tasks (e.g. San Francisco, CA or Melbourne, Australia): </h3><br> <input type="text" name="address" id="userAddress"/><br> <span id="submitUserForm">Search</span><br> </form><br></div><br><div class="acceptedTaskLink clickable">You have already accepted a task! Click here to view instructions</div><br><div class="mapInstructions"><h3>Click on an orange flag to preview a task.</h3></div><br><div class="loading">Loading</div><br><div id="map"></div><br><!--Stores the actual content of the popup divs--><br><div class="popupContent"><br> <div class="splash"><br> <div class="topBar"><span class="close popupButton">x</span></div><br> <div class="content"><br> <p>In this task, you will drive to a given location and answer questions about the area. To perform this task, you must:<br> <ol><br> <li>Choose a location from the map interface</li><br> <li>Print out or write down a short form containing questions about the physical location</li><br> <li>Within 24 hours, <b>drive to the chosen location</b> and answer the questions about the location</li><br> <li>Take pictures of the area <b>using a digital camera</b></li><br> <li>Return to this task, enter in the information you collected, and upload your photos</li><br> <li>Submit the task</li><br> </ol><br> </p><br> <p>You've now accepted the Task through Mechanical Turk, but you now need to accept a particular location in our map interface.<br> To continue, please select one of the following:</p><br> <div class="buttons"><br> <div class="clickable returning">I previously accepted a task here and just need to submit my answer</div><br> <div class="clickable new">I need to browse through the available tasks</div><br> </div><br> </div><br> </div><br> <br> <div class="preview"><br> <div class="topBar"><span class="close popupButton">x</span></div><br> <div class="content"><br> <p><br> <h3>IMPORTANT: After accepting this task AND accepting a location, you will have 24 hours to drive to the location, take photos, and return to your computer to submit the answers.</h3><br> <h3>It may take up to 48 hours to approve your results.</h3><br> </p><br> <p>In this task, you will drive to a given location and answer questions about the area. To perform this task, you must:<br> <ol><br> <li>Choose a location from the map interface</li><br> <li>Print out or write down a short form containing questions about the physical location</li><br> <li>Within 24 hours, <b>drive to the chosen location</b> and answer the questions about the location</li><br> <li>Take pictures of the area <b>using a digital camera</b></li><br> <li>Return to this task, enter in the information you collected, and upload your photos</li><br> <li>Submit the task</li><br> </ol><br> </p><br> <p>Before you accept this task, you should see if any tasks are available in your location. Click the Preview button below to search for tasks in your area.<br> If you find a task that you want to accept, you need to then click the yellow Accept button in the Mechanical Turk inteface (above this frame).</p><br> <div class="clickable preview small">Preview</div><br> </div><br> </div> <br> <br> <div class="confirmReturnUnit"><br> <div class="topBar"><span class="close popupButton">x</span></div><br> <div class="content"><br> You've already accepted a task! Are you sure you want to also accept another one? Make sure you've printed out details of the first task before you accept the next one!<br> </div><br> <div class="buttons"><br> <div class="confirm clickable">I've already printed out details of my last task and want <b>also</b> to accept another one</div><br> <div class="vertPadding"></div><br> <div class="cancel clickable">Never mind, bring me back to the last task I accepted</div><br> </div><br> </div><br> <br> <div class="simpleUnitView"><br> <div class="topBar"><span class="close popupButton">x</span></div><br> <div class="content"><br> <div class="image1">{img1html}</div><br><br> <b>Address:</b> {address}<br><br> <b>City:</b> {city}<br><br> <b>State:</b> {state}<br><br> <b>Country:</b> {country}<br><br> {unitMapLink}<br> </div><br> <div class="previewInstructions"><br> You must accept the task by pressing the yellow "Accept" button above this frame (in the Amazon interface) before you can choose this location for your task.<br> </div><br> <div class="viewMore clickable small">Proceed</div><br> </div><br> <div class="advUnitView"><br> <div class="topBar"><span class="close popupButton">x</span></div><br> <div class="content"><br> <div class="imageHolder"><br> <div class="image1">{img1html}</div><br> <div class="image2">{img2html}</div><br> </div><br> <div class="text"><br> <b>Lat:</b> {Lat}<br><br> <b>Lon:</b> {Lon}<br><br> <b>Street Name:</b> {address}<br><br> <b>City:</b> {city}<br><br> <b>State:</b> {state}<br><br> <b>Country:</b> {country}<br><br> {unitMapLink}<br> </div><br> <div class="instructions"><br> <p>To complete this task, you will need to drive to the specified location with a digital camera and a printout of a short (one-page) questionnaire about the area.<br> To accept the task and display a printable questionnaire to answer about the location, click the button below.</p><br> <p><b>DISCLAIMER: You need to drive to the location and take and upload a JPEG digital photo of the specified location to complete this task.</b></p><br> </div><br> <div class="accept clickable small">Accept this task</div><br> </div><br> </div><br> <br> <div class="checkUnitId"><br> <div class="topBar"><span class="close popupButton">x</span></div><br> <div class="content"><br> <h1>Enter in the UNIT ID code given to you earlier. You must have the UNIT ID to continue with the task:</h1><br> Unit Id: <input type="text" name="unitId" class="unitId hidden"/><br> <table><br> <tr><br> <td> <div class="clickable small checkUnitId">Proceed</div> </td><br> <td> <div class="clickable small cancel">Cancel</div> </td><br> </tr><br> </table><br> </div><br> </div><br> <br> <div class="submittableForm"><br> <div class="topBar"><span class="close popupButton">x</span></div><br> <div class="instructions"><br> <h1>Before submitting the form, make sure that the below information is the correct location (the one that you drove to).</h1><br> <h2>Unit ID:{unitId}</h2><br> <b>Lat:</b> {Lat}<br><br> <b>Lon:</b> {Lon}<br><br> <b>Street Name:</b> {address}<br><br> <b>City:</b> {city}<br><br> <b>State:</b> {state}<br><br> <b>Country:</b> {country}<br><br> <p>Please be <b>as descriptive as possible</b> in your answers!</p><br> <p>Note that it may take up to 48 hours before your work is approved and you are paid. Your work will be manually verified.</p><br> </div><br> <div class="content"><br> <form method="POST"><br> <input type="hidden" name="started_at" class="started_at" value=""/><br> <div class="uploader"><br> <h3>File upload</h3><br> <div class="uploadStatus"><br> <a href="#" class="browse">Choose images of the road</a><br> <div><br> <div class="current-title"></div><br> <img src="/images/progress-bar/bar.gif" class="progress current-progress" /><br> </div><br> <div class="current-text" style="display:none"></div><br> <div><br> <div class="overall-title"></div><br> <img src="/images/progress-bar/bar.gif" class="progress overall-progress" /><br> <ul class="list"></ul><br> </div><br> <input type="button" class="upload" value="Upload these images" style="display:none"/><br> </div><br> </div><br> <div class="vertPadding"></div> <br> </form><br> </div><br> </div><br> <br> <div class="printableForm"><br> <div class="topBar"><span class="close popupButton">x</span></div><br> <div class="instructions"><br> <h1>Print out a copy of these questions. Make sure you write down the UNIT ID, or you will not be able to submit your answers and get paid. Read and follow the instructions carefully!</h1><br> <h2>Unit ID:{unitId}</h2><br> <h3><br> Instructions:<br> <ol><br> <li>Drive to the location shown in the map and specified in the below details.</li><br> <li>Bring a digital camera and a copy of these questions. A digital camera that geotags images (stores the location where they were taken) is preferred, if you have access to one (don't worry--you'll still get paid if you use a regular digital camera). Please use the highest resolution and quality possible on your camera.</li><br> <li>See if there is a street at the location shown in the map with the name given below.</li><br> <li>If so, take a picture of the street and the corresponding street sign containing the name of the street</li><br> <li>EITHER WAY, take <b>at least 4 pictures</b> of the area around the latitude/longtitude position given. Take one photo in each direction (North, East, South, West). <b>IMPORTANT:</b> When taking these four photos, please write on a piece of paper the direction (North, East, etc.) in which you are taking the given photo and then hold this label in the picture. For an example, <a href="http://a1.doloreslabs.com/q82/examples/ex_img_map.JPG">click here</a>.</li><br> <li>If the street mentioned in the task is nearby but not at the latitude/longitude specified, please take a picture of the street sign and make note of the location in as much detail as possible.</li><br> <li>Take as many other pictures as possible to fully provide an understanding of the location and the streets there.</li><br> <li>Answer the questions below for the street and the area around it (the area to consider for this task extends to the edges of the first map image given)</li><br> <li>After you have the answers and photos of the street, refresh the page and choose the option, "I previously accepted a task here and just need to submit my answer".<br> Then enter in the Unit ID ({unitId}).</li><br> <br> </ol><br> <p><br> After you've printed the instructions for the task, if you'd like to accept another location in addition to this one (and do both), click the black X on the right side of the green bar above. Then choose another location by clicking an orange marker.<br> </p><br> </h3><br> <b>Lat:</b> {Lat}<br><br> <b>Lon:</b> {Lon}<br><br> <b>Street Name:</b> {address}<br><br> <b>City:</b> {city}<br><br> <b>State:</b> {state}<br><br> <b>Country:</b> {country}<br><br> {unitMapLink}<br> <div class="imageHolder"><br> <div class="image1">{img1html}</div><br> <div class="image2">{img2html}</div><br> </div><br> </div><br> <div class="content"><br> </div><br> </div><br></div><cml:text label="Text"/>
|
data/spec/gold_spec.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "CML Gold" do
|
4
|
+
before(:each) do
|
5
|
+
@simple = CML::Tags::Text.new <<-CML
|
6
|
+
<cml:text label="Simple" gold="true" valdates="required" />
|
7
|
+
CML
|
8
|
+
@complex = CML::Tags::Select.new <<-CML
|
9
|
+
<cml:select label="Complex">
|
10
|
+
<cml:gold src="complex" matcher="fancy" strict="true" regex="\\.asdf\\." flags="i" no_escape="true"/>
|
11
|
+
<cml:option label="1" />
|
12
|
+
</cml:select>
|
13
|
+
CML
|
14
|
+
@simple_gold = CML::Gold.new(@simple, @simple.gold?)
|
15
|
+
@complex_gold = CML::Gold.new(@complex, @complex.gold?)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "parses a simple example" do
|
19
|
+
@simple_gold.name.should == "simple"
|
20
|
+
@simple_gold.src.should == "simple_gold"
|
21
|
+
@simple_gold.to_hash.should == {"simple"=>"simple_gold"}
|
22
|
+
end
|
23
|
+
|
24
|
+
it "parses a complex example" do
|
25
|
+
@complex_gold.name.should == "complex"
|
26
|
+
@complex_gold.src.should == "complex"
|
27
|
+
@complex_gold.to_hash.should == {"_complex_strict"=>true, "_complex_regex"=>["\\.asdf\\.", "i", "true"], "_complex_matcher"=>"fancy", "complex"=>"complex"}
|
28
|
+
end
|
29
|
+
end
|
data/spec/meta_spec.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "CML.gold" do
|
4
|
+
it "should give me da gold & fields" do
|
5
|
+
cml = <<-HTML
|
6
|
+
<cml:text name="nice" />
|
7
|
+
<cml:group>
|
8
|
+
<cml:group only-if="awesome[1]" class="nice" multiple="true">
|
9
|
+
<div>
|
10
|
+
<cml:checkboxes label="Checkboxes" aggregation="all">
|
11
|
+
<cml:gold src="awesome_gold" regex="\\.asdf\\." flags="i" no_escape="true" strict="true" />
|
12
|
+
<cml:checkbox label="Wanna do it?" />
|
13
|
+
<cml:checkbox label="Sure?" />
|
14
|
+
</cml:checkboxes>
|
15
|
+
</div>
|
16
|
+
<cml:checkbox label="No way">
|
17
|
+
<cml:gold exact="true" structured="true"/>
|
18
|
+
</cml:checkbox>
|
19
|
+
<cml:group multiple="true">
|
20
|
+
<cml:text label="nuts" gold="true"/>
|
21
|
+
</cml:group>
|
22
|
+
<cml:text name="cool" gold="true" aggregation="agg" />
|
23
|
+
</cml:group>
|
24
|
+
<cml:text label="Hot"/>
|
25
|
+
</cml:group>
|
26
|
+
<cml:textarea name="sweet" gold="sweetness" />
|
27
|
+
HTML
|
28
|
+
@p = Parser.new(cml, :prefix => "u12345")
|
29
|
+
#puts @p.golds.inspect
|
30
|
+
@p.should be_valid
|
31
|
+
@p.golds.should == {
|
32
|
+
"_awesome_gold_strict"=>true,
|
33
|
+
"_no_way_1_gold_structured"=>true,
|
34
|
+
"no_way_1"=>"no_way_1_gold",
|
35
|
+
"checkboxes_1"=>"awesome_gold",
|
36
|
+
"nuts_1"=>"nuts_1_gold",
|
37
|
+
"sweet"=>"sweetness",
|
38
|
+
"cool_1"=>"cool_1_gold",
|
39
|
+
"_no_way_1_gold_exact"=>true,
|
40
|
+
"_awesome_gold_regex"=>["\\.asdf\\.", "i", "true"]
|
41
|
+
}
|
42
|
+
@p.fields.should == {
|
43
|
+
"checkboxes_1"=>"all",
|
44
|
+
"cool_1"=>"agg"
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
3
|
+
|
4
|
+
describe "CML Normalize" do
|
5
|
+
it "normalizes everything to checkboxes or text inputs renders template variables" do
|
6
|
+
@p = Parser.new(<<-HTML, {:prefix => "unit[data]", :normalize => true, :data => {"awesome_gold" => ["rad","Neat"], "wowza_gold" => ["Ricky","Martins","Gay",nil], "option" => "Rad"}})
|
7
|
+
<cml:select label="Awesome" validates="required" default="Choose an option" instructions="Just be cool about it">
|
8
|
+
<cml:gold src="awesome_gold" regex="\\.asdf\\." flags="i" no_escape="true" strict="true" />
|
9
|
+
<cml:option label="Awesome" />
|
10
|
+
<cml:option label="Cool" />
|
11
|
+
<cml:option label="{{option}}" />
|
12
|
+
<cml:option label="Neat" />
|
13
|
+
</cml:select>
|
14
|
+
<cml:text label="Opinion" validates="minLength:30" class="large" />
|
15
|
+
<cml:radios label="Hot">
|
16
|
+
<cml:radio label="For sure"/>
|
17
|
+
<cml:radio label="Not" checked="checked" />
|
18
|
+
</cml:radios>
|
19
|
+
<cml:ratings label="Cool" from="Bad" to="Good" />
|
20
|
+
<cml:text label="Sweet" gold="true"/>
|
21
|
+
<cml:meta label="Neat" gold="true"/>
|
22
|
+
<cml:textarea label="Whoa" gold="wowza_gold"/>
|
23
|
+
HTML
|
24
|
+
#puts Parser.escape(@p.to_html).gsub(/\n/,"<br/>")
|
25
|
+
@p.to_html.should sorta_match(<<-HTML)
|
26
|
+
<div class="cml" id="unit[data]">
|
27
|
+
<div class="checkboxes cml_field">
|
28
|
+
<h2 class="legend">Awesome</h2>
|
29
|
+
<div class="cml_row"><label class="">
|
30
|
+
<input name="unit[data][awesome_gold][]" class="awesome_gold validates-required" value="Awesome" type="checkbox" /> Awesome</label></div>
|
31
|
+
<div class="cml_row"><label class="">
|
32
|
+
<input name="unit[data][awesome_gold][]" class="awesome_gold validates-required" value="Cool" type="checkbox" /> Cool</label></div>
|
33
|
+
<div class="cml_row"><label class="">
|
34
|
+
<input checked="checked" name="unit[data][awesome_gold][]" class="awesome_gold validates-required cml_gold_loaded" value="Rad" type="checkbox" /> {{option}}</label></div>
|
35
|
+
<div class="cml_row"><label class="">
|
36
|
+
<input checked="checked" name="unit[data][awesome_gold][]" class="awesome_gold validates-required cml_gold_loaded" value="Neat" type="checkbox" /> Neat</label></div>
|
37
|
+
<p class="instructions">Just be cool about it</p>
|
38
|
+
<div class="cml_gold_reason">
|
39
|
+
<label class="legend">Reason</label>
|
40
|
+
<textarea name="unit[data][awesome_gold_reason]"></textarea>
|
41
|
+
</div>
|
42
|
+
</div>
|
43
|
+
<div class="text cml_field large"><label class="legend">Opinion</label>
|
44
|
+
<div class="cml_row"><input name="unit[data][opinion_gold][]" class="opinion_gold validates-minLength:30 large" value="" type="text" /></div>
|
45
|
+
<div class="cml_gold_reason">
|
46
|
+
<label class="legend">Reason</label>
|
47
|
+
<textarea name="unit[data][opinion_gold_reason]"></textarea>
|
48
|
+
</div>
|
49
|
+
</div>
|
50
|
+
<div class="checkboxes cml_field">
|
51
|
+
<h2 class="legend">Hot</h2>
|
52
|
+
<div class="cml_row"><label class="">
|
53
|
+
<input name="unit[data][hot_gold][]" class="hot_gold" value="For sure" type="checkbox" /> For sure</label></div>
|
54
|
+
<div class="cml_row"><label class="">
|
55
|
+
<input checked="checked" name="unit[data][hot_gold][]" class="hot_gold" value="Not" type="checkbox" /> Not</label></div>
|
56
|
+
<div class="cml_gold_reason">
|
57
|
+
<label class="legend">Reason</label>
|
58
|
+
<textarea name="unit[data][hot_gold_reason]"></textarea>
|
59
|
+
</div>
|
60
|
+
</div>
|
61
|
+
<div class="ratings cml_field">
|
62
|
+
<h2 class="legend">Cool</h2>
|
63
|
+
<div class="cml_row">
|
64
|
+
<table>
|
65
|
+
<thead>
|
66
|
+
<tr>
|
67
|
+
<th></th><th class="">1</th><th class="">2</th><th class="">3</th><th class="">4</th><th></th>
|
68
|
+
</tr>
|
69
|
+
</thead>
|
70
|
+
<tbody>
|
71
|
+
<tr>
|
72
|
+
<td>Bad</td>
|
73
|
+
<td class="">
|
74
|
+
<input name="unit[data][cool_gold][]" class="cool_gold" value="1" type="checkbox" /> 1
|
75
|
+
</td>
|
76
|
+
<td class="">
|
77
|
+
<input name="unit[data][cool_gold][]" class="cool_gold" value="2" type="checkbox" /> 2
|
78
|
+
</td>
|
79
|
+
<td class="">
|
80
|
+
<input name="unit[data][cool_gold][]" class="cool_gold" value="3" type="checkbox" /> 3
|
81
|
+
</td>
|
82
|
+
<td class="">
|
83
|
+
<input name="unit[data][cool_gold][]" class="cool_gold" value="4" type="checkbox" /> 4
|
84
|
+
</td>
|
85
|
+
<td>Good</td>
|
86
|
+
</tr>
|
87
|
+
</tbody>
|
88
|
+
</table>
|
89
|
+
</div>
|
90
|
+
<div class="cml_gold_reason">
|
91
|
+
<label class="legend">Reason</label>
|
92
|
+
<textarea name="unit[data][cool_gold_reason]"></textarea>
|
93
|
+
</div>
|
94
|
+
</div>
|
95
|
+
<div class="text cml_field">
|
96
|
+
<label class="legend">Sweet</label>
|
97
|
+
<div class="cml_row"><input name="unit[data][sweet_gold][]" class="sweet_gold" value="" type="text" /></div>
|
98
|
+
<div class="cml_gold_reason">
|
99
|
+
<label class="legend">Reason</label>
|
100
|
+
<textarea name="unit[data][sweet_gold_reason]"></textarea>
|
101
|
+
</div>
|
102
|
+
</div>
|
103
|
+
<div class="text cml_field">
|
104
|
+
<label class="legend">Neat</label>
|
105
|
+
<div class="cml_row"><input name="unit[data][neat_gold][]" class="neat_gold" value="" type="text" /></div>
|
106
|
+
<div class="cml_gold_reason">
|
107
|
+
<label class="legend">Reason</label>
|
108
|
+
<textarea name="unit[data][neat_gold_reason]"></textarea>
|
109
|
+
</div>
|
110
|
+
</div>
|
111
|
+
<div class="textarea cml_field">
|
112
|
+
<label class="legend">Whoa</label>
|
113
|
+
<div class="cml_row">
|
114
|
+
<textarea name="unit[data][wowza_gold][]" class="wowza_gold cml_gold_loaded">Ricky</textarea>
|
115
|
+
</div>
|
116
|
+
<div class="cml_row">
|
117
|
+
<textarea name="unit[data][wowza_gold][]" class="wowza_gold cml_gold_loaded">Martins</textarea>
|
118
|
+
</div>
|
119
|
+
<div class="cml_row">
|
120
|
+
<textarea name="unit[data][wowza_gold][]" class="wowza_gold cml_gold_loaded">Gay</textarea>
|
121
|
+
</div>
|
122
|
+
<div class="cml_row">
|
123
|
+
<textarea name="unit[data][wowza_gold][]" class="wowza_gold"></textarea>
|
124
|
+
</div>
|
125
|
+
|
126
|
+
<div class="cml_gold_reason">
|
127
|
+
<label class="legend">Reason</label>
|
128
|
+
<textarea name="unit[data][wowza_gold_reason]"></textarea>
|
129
|
+
</div>
|
130
|
+
</div>
|
131
|
+
</div>
|
132
|
+
HTML
|
133
|
+
end
|
134
|
+
|
135
|
+
it "normalizes everything to checkboxes or text inputs" do
|
136
|
+
@p = Parser.new(<<-HTML, {:prefix => "unit[data]", :normalize => true, :data => {"opinion_gold" => ["rad","Neat \"right\""]}})
|
137
|
+
<cml:group label="Foo bar">
|
138
|
+
<cml:text label="Opinion" validates="minLength:30" class="large" gold="true" />
|
139
|
+
</cml:group>
|
140
|
+
HTML
|
141
|
+
#puts Parser.escape(@p.to_html).gsub(/\n/,"<br/>")
|
142
|
+
@p.to_html.should sorta_match(<<-HTML)
|
143
|
+
<div class="cml" id="unit[data]">
|
144
|
+
<div class="group">
|
145
|
+
<label class="legend">Foo bar</label>
|
146
|
+
<div class="text cml_field large">
|
147
|
+
<label class="legend">Opinion</label>
|
148
|
+
<div class="cml_row">
|
149
|
+
<input name="unit[data][opinion_gold][]" type="text" value="rad" class="opinion_gold validates-minLength:30 large cml_gold_loaded" />
|
150
|
+
</div>
|
151
|
+
<div class="cml_row">
|
152
|
+
<input name="unit[data][opinion_gold][]" type="text" value="Neat "right"" class="opinion_gold validates-minLength:30 large cml_gold_loaded" />
|
153
|
+
</div>
|
154
|
+
<div class="cml_gold_reason">
|
155
|
+
<label class="legend">Reason</label>
|
156
|
+
<textarea name="unit[data][opinion_gold_reason]"></textarea>
|
157
|
+
</div>
|
158
|
+
</div>
|
159
|
+
</div>
|
160
|
+
</div>
|
161
|
+
HTML
|
162
|
+
end
|
163
|
+
|
164
|
+
it "normalizes iterate" do
|
165
|
+
@p = Parser.new(<<-HTML, {:prefix => "unit[data]", :normalize => true, :data => {"multi_choice_gold" => ["one",["one","two"]], "wow" => ["1","2"]}})
|
166
|
+
<cml:iterate on="wow">
|
167
|
+
<cml:checkboxes label="Multi choice" gold="true">
|
168
|
+
<cml:checkbox label="One" />
|
169
|
+
<cml:checkbox label="Two" checked="checked" />
|
170
|
+
</cml:checkboxes>
|
171
|
+
</cml:iterate>
|
172
|
+
HTML
|
173
|
+
#puts Parser.escape(@p.to_html).gsub(/\n/,"<br/>")
|
174
|
+
@p.to_html.should sorta_match(<<-HTML)
|
175
|
+
<div class="cml" id="unit[data]">
|
176
|
+
<div class="iterate">
|
177
|
+
<div class="cml_nugget">
|
178
|
+
<div class="checkboxes cml_field"><h2 class="legend">Multi choice</h2>
|
179
|
+
<div class="cml_row"><label class="">
|
180
|
+
<input name="unit[data][multi_choice_gold][0][]" type="checkbox" value="One" class="multi_choice_gold cml_gold_loaded" checked="checked" />
|
181
|
+
One
|
182
|
+
</label></div>
|
183
|
+
<div class="cml_row"><label class="">
|
184
|
+
<input name="unit[data][multi_choice_gold][0][]" type="checkbox" value="Two" class="multi_choice_gold" />
|
185
|
+
Two
|
186
|
+
</label></div>
|
187
|
+
|
188
|
+
<div class="cml_gold_reason">
|
189
|
+
<label class="legend">Reason</label>
|
190
|
+
<textarea name="unit[data][multi_choice_gold_reason][]"></textarea></div>
|
191
|
+
</div>
|
192
|
+
</div>
|
193
|
+
<div class="cml_nugget">
|
194
|
+
<div class="checkboxes cml_field">
|
195
|
+
<h2 class="legend">Multi choice</h2>
|
196
|
+
<div class="cml_row"><label class="">
|
197
|
+
<input name="unit[data][multi_choice_gold][1][]" type="checkbox" value="One" class="multi_choice_gold cml_gold_loaded" checked="checked" />
|
198
|
+
One
|
199
|
+
</label></div>
|
200
|
+
<div class="cml_row"><label class="">
|
201
|
+
<input name="unit[data][multi_choice_gold][1][]" type="checkbox" value="Two" class="multi_choice_gold cml_gold_loaded" checked="checked" />
|
202
|
+
Two
|
203
|
+
</label></div>
|
204
|
+
|
205
|
+
<div class="cml_gold_reason">
|
206
|
+
<label class="legend">Reason</label>
|
207
|
+
<textarea name="unit[data][multi_choice_gold_reason][]"></textarea></div>
|
208
|
+
</div>
|
209
|
+
</div>
|
210
|
+
</div>
|
211
|
+
</div>
|
212
|
+
HTML
|
213
|
+
end
|
214
|
+
end
|