Categories
Customize Vista Edit

Customize Vista Edit

The Customize Vista Edit is a script that adds to the features found when editing a course in the Build mode of UBC Vista courses. When installed onto Greasemonkey, the Customize Vista Edit allows course builders to: quick or full preview their HTML code, revert to previous code, and expand the textbox for better viewing. This report is focused on the design and development of the Customize Vista Edit script, and will elaborate on its included features.

Customize Vista Edit

Customize Vista Edit

Title Image

Prepared By:

Henry Lo


ABSTRACT

The Customize Vista Edit is a script that adds to the features found when editing a course in the Build mode of UBC Vista courses. When installed onto Greasemonkey, the Customize Vista Edit allows course builders to: quick or full preview their HTML code, revert to previous code, and expand the textbox for better viewing. This report is focused on the design and development of the Customize Vista Edit script, and will elaborate on its included features.

Table of Contents

ABSTRACT. 2

1.0 INTRODUCTION.. 5

2.0 BACKGROUND.. 6

3.0 CODING.. 7

3.1 FormParams. 7

3.2 Quick Preview.. 8

3.3 Save Code. 9

3.4 Revert 10

3.5 Resize. 10

3.6 Full Preview.. 13

3.7 Layout 13

4.0 CONCLUSION.. 15

APPENDIX I 16

Table of Figures

Figure 1. Greasemonkey – Manage Script 5

Figure 2. Customize Vista Edit layout 5

Figure 3. Quick Preview.. 8

Figure 4. Save Buttons. 9

Figure 5. Revert Prompt 10

Figure 6. Revert Button. 10

Figure 7. Textbox: Expand. 12

Figure 8. Textbox: Reset 12

Figure 9. Layout 14

1.0  INTRODUCTION

The Customize Vista Edit script is an intuitive addition to the course editor found in the build mode of UBC Vista. To use it, the user must have the Mozilla Firefox add-on Greasemonkey already running on their browser. Greasemonkey is a program that allows users to install scripts that make on-the-fly changes to HTML webpage content on the DOMContentLoaded event, which happens immediately after it is loaded in the browser. For example, downloading a text area size adjuster onto Greasemonkey will allow users to adjust any textboxes found in any website.

To download the Customize Vista Edit, use the following link:

http://oltubc.com/customizevistaedit.user.js

Greasemonkey Manage Script

Figure 1. Greasemonkey – Manage Script

After completing the installation, enabling the script will activate it. From now on, whenever the user enters the build mode and edits a course report, for example, the Customize Vista Edit toolbar will appear with new options for the user that will allow for more convenient editing.

Customize Vista Toolbar

Figure 2. Customize Vista Edit layout

2.0  BACKGROUND

The Customize Vista Edit script is mostly developing with JavaScript coding.

JavaScript is an object-oriented scripting language used to enable programmatic access to objects within both the client application and other applications. It is primarily used as an integrated component of the web browser, allowing the development of enhanced user interfaces and dynamic websites.

3.0  CODING

This section of the report will begin discussing the development of the Customize Vista Edit script. Each section will focus on the features added by Customize Vista Edit and will take an in-depth analysis and explain how each feature was developed and help you better understand the code behind it. (Refer to Appendix I)

3.1 FormParams

The FormParams function is developed to take a form and translates the elements into an AJAX ready sequence of parameters. The reason for implementing this function is to allow the save function, discussed later, to save changes without having to exit the page every time. This would allow the user to make quick changes and preview the code and make changes conveniently.  The inputs that the FormParams function scans are separated into two types, regular form inputs (title), and text areas (HTML textbox). The code for retrieving the inputs are as follows:

// Get all Inputs

var finputs = form.getElementsByTagName(‘input’);

var farray = new Array();

for(var i = 0; i < finputs.length; i++){

if(finputs[i].name.length > 0){

farray[i] = finputs[i].name + “=” + encodeURI(finputs[i].value);

}

}

The function first assigns the input tag to the variable finputs. Then, it will enter a ‘for’ loop in which it will scan each character of the input and translates the elements into AJAX. Scanning the text areas is the same.

// Get all Textareas

var farray2 = new Array();

var ftextarea = form.getElementsByTagName(‘textarea’);

for(var i = 0; i < ftextarea.length; i++){

if(ftextarea[i].name.length > 0){

farray2[i] = ftextarea[i].name + “=” + encodeURIComponent(ftextarea[i].value);

}

}

3.2 Quick Preview

The preview button found on the Customize Vista Edit layout is used to generate a demo page. This allows users to quickly view their current page and make changes. The function starts out by scanning the HTML textbox using the method getElementById(). This method returns a reference to the first object with the specified ID, which in this case is ‘htmlText’. Next, it takes the values inside the textbox using textarea.value and stores it, as values, into ttransfer.

// Get the html source from textarea

var textarea = document.getElementById(‘htmlText’);

var semiwrap = document.createElement(‘div’);

var ttransfer = textarea.value;

Then it transfers the values in ttransfer and sets the HTML syntax describing the element’s descendants into the variable semiwrap using .innerHTML. This method takes the text and converts it into HTML format:

semiwrap.innerHTML = ttransfer;

document.getElementById(‘wrap’).innerHTML = semiwrap.innerHTML;

Quick Preview

Figure 3. Quick Preview

Due to the nature of Vista’s addressing issues, much of the source code from the textbox is different; therefore some measures have been taken to fix links and images before preview. The below code implements this:

// Replace image and link paths for local view

ttransfer = ttransfer.replace(/(src=(\”|\’))(\.\.\/)?([0-9a-zA-Z\/_?+-.]+)(\”|\’)/g, “$1” + newroot + folder + “/$3$4$5”);

ttransfer = ttransfer.replace(/(href=(\”|\’))(\.\.\/)?([0-9a-zA-Z\/_?+-.]+)(\”|\’)/g, “$1” + newroot + folder + “/$3$4$5”);

3.3 Save Code

The save code function is a simple algorithm that allows the user to save their current source code by means of AJAX http protocols. By using AJAX, preventions allow Vista from redirecting back to the item menu allowing further changes if the last edits were not satisfactory. The code start by requesting the http protocol:

var http = new XMLHttpRequest();

if(http.overrideMimeType)

{

http.overrideMimeType(‘text/html’);

}

Next, it retrieves the parameters and initializes the header utilizing the formparams function discussed earlier. Now space has been created to save the current code. The following code sends the header information and waits for the http to respond, letting the user know that their code has been successfully saved.

// Get form parameters and action

var params = unsafeWindow.formparams(document.forms[0]);

var url = unsafeWindow.formaction(document.forms[0]);

// Initialize a header

http.open(“POST”, root + url, true);

// Send Header Information

http.setRequestHeader(“Content-type”, “application/x-www-form-urlencoded”);

http.setRequestHeader(“Content-length”, params.length);

http.setRequestHeader(“User-Agent”, “Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11”);

http.setRequestHeader(“Accept-Charset”, “ISO-8859-1,utf-8;q=0.7,*;q=0.7”);

http.setRequestHeader(“Keep-Alive”, “300”);

http.setRequestHeader(“Connection”, “close”);

// Wait for a http response

http.onreadystatechange = function() {//Call a function when the state changes.

if(http.readyState == 4 && http.status == 200) {

alert(“Changes Saved”);

}

}

// end onreadystatechange

http.send(params);

Save Button

Figure 4. Save Buttons

3.4 Revert

The “Revert” button is to allow users that have made a mistake when writing the HTML source code to go back to the version of the source code that first appeared in the current session. The code is very simple for the implementation of this feature. First, the function scans the HTML textbox using the method getElementById(). This method returns a reference to the first object with the specified ID, which in this case is ‘htmlText’.

// oCode = Original Code

var rtextarea = document.getElementById(‘htmlText’);

Then it prompts a warning message asking “Are you sure you want to revert the document”, if the user clicks yes, the code will return to the code present at the start of the current session, where oCode is the original source code.

Revert Prompt

Figure 5. Revert Prompt

// Make sure the user really wants to undo ALL the modifications

var answer = confirm(“Are you sure you want to revert the document?”, 2, 2);

// I think the answer comes in binary / bool

if(answer){

rtextarea.value = oCode; }

Revert Bar

Figure 6. Revert Button

3.5 Resize

The resize function is a more complex algorithm as it utilizes both javascript and CSS coding in the expansion of the HTML textbox. CSS, Cascading Style Sheets, is designed primarily to enable the separation of document content (written in HTML or a similar markup language) from document presentation, including elements such as the colors, fonts, and layout. This separation can improve content accessibility and provide more flexibility and control. The reason for using CSS is to improve the layout. When using JavaScript coding for the expansion of the textbox, the box collides with other items on the page, causing unwanted obstructions. As CSS is designed for improving page layout, its usefulness in this case is unquestionable. First, initialization of CSS to be used within Greasemonkey is required, this is demonstrated by the below code:

// inserts the ability to use CSS stylex

// =====================================

function addGlobalStyle(css) {

var head, style;

head = document.getElementsByTagName(‘head’)[0];

if(!head) {return;}

style = document.createElement(‘style’);

style.type = ‘text/css’;

style.innerHTML = css;

head.appendChild(style);  }

This code allows the use of CSS styles within the script. Next we can adjust the height and width of the textbox by first specifying its class and then adjust the size accordingly.

unsafeWindow.resizefcn = function (){

// Inserts the ability to edit the style of the page with CSS

addGlobalStyle(‘.descForm {height: 500px; width: 700px;}’);

}

In addition, the feature to change back to the original size was implemented. After the user resizes the textbox, the button will change from Textbox: Expand to Textbox: Reset. This is accomplished by including the following code in the resize function:

resize.value = “Textbox: Reset”;

resize.setAttribute(“onClick”, “resetfcn()”);

thediv.appendChild(reset);

And the following code in the reset function, which resets the textbox size back to the original:
// Inserts the ability to edit the style of the page with CSS

addGlobalStyle(‘.descForm {height: 120px; width: 400px;}’);

resize.value = “Textbox: Expand”;

resize.setAttribute(“onClick”, “resizefcn()”);

thediv.appendChild(resize);

Textbox Expand 1Textbox Expand 2

Figure 7. Textbox: Expand

Textbox Reset

Figure 8. Textbox: Reset

3.6 Full Preview

This function generates a full popup window preview of the current page. This function first grabs the current page ID and then gets the page address along with its parameters followed by opening the popup window. These steps are implemented by the following code:

// Grab the current page ID

var pageid = document.getElementsByName(‘pageID’)[0].value;

var page = document.getElementsByName(‘linkedToFilePath’)[0];

// Get the page link along with it’s parameters

var viewer = “https://www.vista.ubc.ca/webct/ContentPageServerServlet/” + page.value + “?pageID=” + pageid;

// Open the popup window

window.open(viewer,’popup_preview’,’width=800,height=640,menubar=1,toolbar=1,scrollbars=1,status=1,location=1,resizable=1′)

3.7 Layout

Now, we need buttons for the features we implemented above. To create these buttons using JavaScript, we first start by initializing variables and values according to each button.

var preview = cancel.cloneNode(true);

preview.value = “Full Preview”;

var save = cancel.cloneNode(true);

save.value = “Save Changes”;

var revert = cancel.cloneNode(true);

revert.value = “Revert”;

var resize = cancel.cloneNode(true);

resize.value = “Textbox: Expand”;

Next, we assign the functions to their respective buttons:

preview.setAttribute(“onClick”, “fullPreview()”);

save.setAttribute(“onClick”, “saveCode()”);

revert.setAttribute(“onClick”, “revert(originalCode)”);

resize.setAttribute(“onClick”, “resizefcn(originalCode)”);

With the buttons created, we now create the layout. To have spaces between each button, we use the following code:

// aspan is just a little gap I use to separate

// the custom buttons I created

for(var i = 0; i < 2; i++){

aspan = aspan.cloneNode(true);

thediv.appendChild(aspan);}

The final product is:

Customize Vista Toolbar

Figure 9. Layout

4.0  CONCLUSION

The Customize Vista Edit script is an intuitive and convenient addition to the course editor in UBC Vista. With its addition, users can quick preview their source code, save their current code without needing to exit the page, resize and rest the textbox,   and revert to the original source code. The development of the script utilized both JavaScript and CSS languages to implement the features of the Customize Vista Edit. The Customize Vista Edit script is aimed to convenient web designer in UBC Vista, and additional features are being considered to allow users a more streamline experience during web development.

APPENDIX I

// ==UserScript==

// @name           Customize Vista Edit

// @namespace      Customize Vista Edit

// @include        https://www.*.ubc.ca/webct*editOrganizerResource.dowebct?*selectedResourceType=PAGE_TYPE*

// @include        https://www.*.ubc.ca/webct*viewCourseMapItemDispatcher.dowebct?*&tab=build&targetFrame=RIGHTTOOLFRAME*

// @include                                 https://www.*.ubc.ca/webct*linkedToResource.dowebct?*&selectedResourceType=PAGE_TYPE&selectedResourceID=*

// ==/UserScript==

// Last Edit: April 28th, 2008

// ===========================

// Thoughts…

// :: Some possible functions to implement – Detect when target site doesn’t really save any changes to document

// :: Modify to use AJAX frameworks (eg, jQuery) for easy upgrade

// :: Port this code to a Safari/Greasekit for the stupid Macs, main modifictions would be to change unsafeWindow element

//                to GreaseKit compliant object

// Active Editing

// ==============

// If turned onto true, quick preview changes will be updated

// in real time, however, it’s fairly slow. Turned off for efficiency

var active = false;

var h = 500 + “px”;

var w = 500 + “px”;

var count=0;

// Vista Server

var root = “https://www.vista.ubc.ca”;

// File Root Folder Declaration

var folder = document.getElementById(‘folderPath’).value.split(“/”)[1];

// Create an invisible DIV Wrapper for easy js access later

var wrap = document.createElement(“div”);

wrap.setAttribute(“id”, “wrap”);

// inserts the ability to use CSS styles

// =====================================

function addGlobalStyle(css) {

var head, style;

head = document.getElementsByTagName(‘head’)[0];

if(!head) {return;}

style = document.createElement(‘style’);

style.type = ‘text/css’;

style.innerHTML = css;

head.appendChild(style);

}

/*

// Custom Function getElementsByClassName

// ======================================

// – This should’ve been prototyped for elements but

// for the purposes, this should be okay

// Takes in the name from the “class=” attribute

document.getElementsByClassName = function(clsName){

var retVal = new Array();

var elements = document.getElementsByTagName(“*”);

for(var i = 0;i < elements.length;i++){

if(elements[i].className.indexOf(” “) >= 0){

var classes = elements[i].className.split(” “);

for(var j = 0;j < classes.length;j++){

if(classes[j] == clsName)

retVal.push(elements[i]);

}

}

else if(elements[i].className == clsName)

retVal.push(elements[i]);

}

return retVal;

}

*/

// unsafeWindow :: FormParams

// ==========================

// Takes a form and translates the elements into a AJAX

// ready sequence of parameters (eg, name=jack&age=18&comment=…)

// Separated into two types, regular form inputs and textareas

// Class unsafeWindow due to user-action property

unsafeWindow.formparams = function(form){

// Get all Inputs

var finputs = form.getElementsByTagName(‘input’);

var farray = new Array();

for(var i = 0; i < finputs.length; i++){

if(finputs[i].name.length > 0){

farray[i] = finputs[i].name + “=” + encodeURI(finputs[i].value);

}

}

// Get all Textareas

var farray2 = new Array();

var ftextarea = form.getElementsByTagName(‘textarea’);

for(var i = 0; i < ftextarea.length; i++){

if(ftextarea[i].name.length > 0){

farray2[i] = ftextarea[i].name + “=” + encodeURIComponent(ftextarea[i].value);

}

}

return farray.join(“&”) + “&” + farray2.join(“&”);;

}

// unsafeWindow :: FormAction

// ==========================

// Takes a form and retrieves the “action=” parameter

// Once again, it’s for AJAX calls later

// Class unsafeWindow due to user-action property

unsafeWindow.formaction = function(form){

return form.getAttribute(“action”);

}

// unsafeWindow :: PreviewCode

// ===========================

// Function called by preview code button to generate a demo page

// Due to the nature of Vista’s addressing issues, much of the source

// code from textarea is different, therefore some measures have been

// taken place to fix these links before previewed (src for images,

// href for links and frames, etc)

// Class unsafeWindow due to user-action property

unsafeWindow.previewCode = function (){

// Get the html source from textarea

var textarea = document.getElementById(‘htmlText’);

var semiwrap = document.createElement(‘div’);

var ttransfer = textarea.value;

// Make a local root to avoid auto path prefix from browser

var newroot = “https://www.vista.ubc.ca/webct/RelativeResourceManager/Template/”;

// Replace image and link paths for local view

ttransfer = ttransfer.replace(/(src=(\”|\’))(\.\.\/)?([0-9a-zA-Z\/_?+-.]+)(\”|\’)/g, “$1” + newroot + folder + “/$3$4$5”);

ttransfer = ttransfer.replace(/(href=(\”|\’))(\.\.\/)?([0-9a-zA-Z\/_?+-.]+)(\”|\’)/g, “$1” + newroot + folder + “/$3$4$5”);

semiwrap.innerHTML = ttransfer;

document.getElementById(‘wrap’).innerHTML = semiwrap.innerHTML;

}

// unsafeWindow :: saveCode

// Save the source code by means of AJAX http protocols

// This prevents Vista from redirecting back to the item menu

// allowing further changes if the last edits were not satisfactory

// ** Important :: If for some peculiar reason the file is not saved

// it will still say “Changes Saved”, one way to fix this is to

// to scan the http.responseText for any error messages

// Class unsafeWindow due to user-action property

unsafeWindow.saveCode = function (){

var http = new XMLHttpRequest();

if(http.overrideMimeType){

http.overrideMimeType(‘text/html’);

}

// Get form parameters and action

var params = unsafeWindow.formparams(document.forms[0]);

var url = unsafeWindow.formaction(document.forms[0]);

// Initialize a header

http.open(“POST”, root + url, true);

// Send Header Information

http.setRequestHeader(“Content-type”, “application/x-www-form-urlencoded”);

http.setRequestHeader(“Content-length”, params.length);

http.setRequestHeader(“User-Agent”, “Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11”);

http.setRequestHeader(“Accept-Charset”, “ISO-8859-1,utf-8;q=0.7,*;q=0.7”);

http.setRequestHeader(“Keep-Alive”, “300”);

http.setRequestHeader(“Connection”, “close”);

// Wait for a http response

http.onreadystatechange = function() {//Call a function when the state changes.

if(http.readyState == 4 && http.status == 200) {

alert(“Changes Saved”);

}

}

// end onreadystatechange

http.send(params);

}

// unsafeWindow :: Revert

// ======================

// Session based revert function. This reverts any changes to the original

// source code that was first opened in the current session. This does Not

// revert to the last “working” save”.

// Class unsafeWindow due to user-action property

unsafeWindow.revert = function (oCode){

// oCode = Original Code

var rtextarea = document.getElementById(‘htmlText’);

// Make sure the user really wants to undo ALL the modifications

var answer = confirm(“Are you sure you want to revert the document?”, 2, 2);

// I think the answer comes in binary / bool

if(answer){

rtextarea.value = oCode;

}

}

// unsafeWindow :: Resize

// ======================

// Expands the textarea

// Class unsafeWindow due to user-action property

unsafeWindow.resizefcn = function (){

// Inserts the ability to edit the style of the page with CSS

addGlobalStyle(‘.descForm {height: 500px; width: 700px;}’);

resize.value = “Textbox: Reset”;

resize.setAttribute(“onClick”, “resetfcn()”);

thediv.appendChild(reset);

}

// unsafeWindow :: Reset

// ======================

// Resets the textarea

// Class unsafeWindow due to user-action property

unsafeWindow.resetfcn = function (){

// Inserts the ability to edit the style of the page with CSS

addGlobalStyle(‘.descForm {height: 120px; width: 400px;}’);

resize.value = “Textbox: Expand”;

resize.setAttribute(“onClick”, “resizefcn()”);

thediv.appendChild(resize);

}

// unsafeWindow :: FullPreview

// ===========================

// This function generates a full (popup) preview of the current

// page as if the user were to click on action menu -> preview page

// Class unsafeWindow due to user-action property

// User Prompted Action, must be of class unsafeWindow

unsafeWindow.fullPreview = function (){

// Grab the current page ID

var pageid = document.getElementsByName(‘pageID’)[0].value;

var page = document.getElementsByName(‘linkedToFilePath’)[0];

// Get the page link along with it’s parameters

var viewer = “https://www.vista.ubc.ca/webct/ContentPageServerServlet/” + page.value + “?pageID=” + pageid;

// Open the popup window

window.open(viewer,’popup_preview’,’width=800,height=640,menubar=1,toolbar=1,scrollbars=1,status=1,location=1,resizable=1′)

}

//  ==================================================================================

// Figure out where we are and what we need

// Get the current address (to get the ID of the current page

var address = document.location.toString();

var rawid;

// Check which page we are in and get rawID

if(address.indexOf(“viewCourseMapItemDispatcher.dowebct”)!=-1){

rawid = address.split(“componentId=”)[1];}

else{

rawid = address.split(“selectedResourceID=”)[1];}

// … get rawID

var id = rawid.split(“&”)[0];

// For Active Editing Only

var textarea = document.getElementById(‘htmlText’);

// Activate real-time preview

// Warning :: Slow

if(active){

textarea.setAttribute(“onKeyUp”, “previewCode()”);}

// Adjust the differences between the annoying MAC

// and the awesome PC. For some reason, Vista renders

// differently on a MAC and PC

var div_size = 350;

var tdiv;

// Fix the Textarea Size;

if(navigator.appVersion.indexOf(“Win”)!=-1){

tdiv = document.getElementById(‘formTag’);

tdiv.style.height = div_size + “px !important”;

}

textarea.style.height = (div_size-15) + “px !important”;

textarea.style.width = “800px !important”;

// Expand the textarea to a bigger size for better editing

document.forms.namedItem(“editPageForm”).elements.namedItem(“htmlText”).setAttribute(‘rows’, 50);

// Fix the Page Squeeze Problem

mystyle = document.styleSheets[0];

// Save a copy of the original code before any modifications

unsafeWindow.originalCode = textarea.value;

// Create a break and insert our Quick Preview

document.body.appendChild(document.createElement(“br”));

document.body.appendChild(wrap);

// Start adding buttons from previous buttons

// supplied by Vista.

// Create & insert Exit button, this button does not

// save any changes.

var theform = document.forms[0];

var inputs = document.getElementsByTagName(‘input’);

var cancel = inputs[inputs.length-1];

cancel.value = “Exit”;

// Create & insert our Save button

// Rename our save and exit button

var oSave = inputs[inputs.length-2];

oSave.value = “Save and Exit”;

var preview = cancel.cloneNode(true);

var save = cancel.cloneNode(true);

var revert = cancel.cloneNode(true);

var thediv = cancel.parentNode;

// Create & insert our FullPreview button

preview.value = “Full Preview”;

save.value = “Save Changes”;

revert.value = “Revert”;

var aspan = document.createElement(“span”);

aspan.innerHTML = “&nbsp;”;

// Assign the buttons their functions

preview.setAttribute(“onClick”, “fullPreview()”);

save.setAttribute(“onClick”, “saveCode()”);

revert.setAttribute(“onClick”, “revert(originalCode)”);

// aspan is just a little gap I use to separate

// the custom buttons I created

for(var i = 0; i < 2; i++){

aspan = aspan.cloneNode(true);

thediv.appendChild(aspan);

}

thediv.appendChild(save);

// Add the Quick Preview Button

if(!active){

var quickpreview = cancel.cloneNode(true);

quickpreview.value = “Quick Preview”;

quickpreview.setAttribute(“onClick”, “previewCode()”);

for(var i = 0; i < 2; i++){

aspan = aspan.cloneNode(true);

thediv.appendChild(aspan);

}

thediv.appendChild(quickpreview);

}

// Add some Spaces

for(var i = 0; i < 2; i++){

aspan = aspan.cloneNode(true);

thediv.appendChild(aspan);

}

// Add the Full Preview Button

thediv.appendChild(preview);

// Add some extra Spaces

for(var i = 0; i < 2; i++){

aspan = aspan.cloneNode(true);

thediv.appendChild(aspan);

}

// Add the Revert Button

thediv.appendChild(revert);

// Add some extra Spaces

for(var i = 0; i < 2; i++){

aspan = aspan.cloneNode(true);

thediv.appendChild(aspan);

}

var resize = cancel.cloneNode(true);

resize.value = “Textbox: Expand”;

resize.setAttribute(“onClick”, “resizefcn()”);

thediv.appendChild(resize);

// Initialize a first Preview Code

unsafeWindow.previewCode();

Leave a Reply

Your email address will not be published. Required fields are marked *

Spam prevention powered by Akismet