using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; // This is from the reference we set to AlchemiumInterfaces.dll // The AlchemiumInterfaces.dll assembly is located in the SDK_ROOT\ext directory // With each new application you build it will live in the ./app/ext directory, // which also where you put any extensions you want the application to use. using AlchemiumInterfaces; namespace SampleExtension { public class Class1 : AlchemiumInterfaces.IAlchemiumExt { private IAlchemiumAPI _api; // This is the first call Alchemium will make after instantiating our // extension. We will hold on the the _api reference passed to // us for future use in communicating with the host. void IAlchemiumExt.init(IAlchemiumAPI api) { // Stash the reference to the host API _api = api; } void IAlchemiumExt.closeDown() { // Called by the ALchemium runtime when the host application is closing // Do any required recource cleanup here } // This is the fully qualified object name. Note, the reverse domain // naming scheme is required to avoid collisions string IAlchemiumExt.objectName { // This will be the object prefix to our extension in JavaScript get { return "com.electricplum.myExt"; } } // Return the list of function names you are going to present to // JavaScript via your object. when JS calls one of these functions, // The IAlchemiumExt.invoke implementation will be called in this extension List<string> IAlchemiumExt.getFunctionNames() { var funcs = new List<string>(); funcs.Add("func1"); funcs.Add("func2"); // ... etc ... // These will all ultimately be hanging off your object name // for example com.electricplum.myExt.func1(); return funcs; } // Each time JavaScript on the page makes a call to one of our registered // functions, IAlchemiumExt.invoke() will be called. Here we handle // the call and return a response Dictionary<string, object> IAlchemiumExt.invoke(string methodName, Dictionary<string, object> argsIn) { // In JavaScript you call these functions using the prefix returned by // our implementation of IAlchemiumExt.objectName // So in this example we would use this JS code: // // var ret = com.electricplum.myExt.func1({someParam: 'passing this to .net'}); // var ret = com.electricplum.myExt.func2(); // // We will populate this dictionary with our return values var ret = new Dictionary<string, object>(); switch (methodName) { case "func1": // This function returns an object with 2 properties "prop1" and "prop2" ret.Add("prop1", 42); // If the JS caller passed in a param named "someParam" echo it in the "prop2" // property of the object we return if (argsIn.ContainsKey("someParam")) { ret.Add("prop2", "Hello, you passed in " + argsIn["someParam"]); } else { ret.Add("prop2", "Hello, you didn't pass a value for someParam"); } return ret; case "func2": // Example of using the Alchemium API's stringify method to pass // back a native c# object in JSON format. We can use JSON.parse() in // JavaScript to deserialize it to a JS object var o = new SerializeTest(); o.propertyOne = "I am property one"; o.propertyTwo = 3.14; ret.Add("obj", _api.stringify(o)); return ret; default: return null; } } // Register for custom schemes we'll listen for any requests (href, AJAX etc) to these uri schemes // will be routed to our implementation of IAlchemiumExt.processCustomSchemeRequest List<AlchemiumScheme> IAlchemiumExt.getCustomSchemes() { var schemeList = new List<AlchemiumScheme>(); var myScheme = new AlchemiumScheme(); // http is the preferred prefix to avoid having to deal with the host Alchemium browser // imposing security restrictions on things like post data to non standard URI schemes myScheme.uriPrefix = "http"; myScheme.domain = "myextension.com"; myScheme.mimeType = "text/html"; schemeList.Add(myScheme); // At this point, any request to "http://myExtension.com/*" (AJAX, href etc.) will // be routed to our implementation of IAlchemiumExt.processCustomSchemeRequest() return schemeList; } // A request for a resource was made (either from the HTML content or AJAX) // to a scheme that matches one that we are listening for // We show both variants here. First we handle an AJAX request/response, and // next we see how we could silmply return content as if it were generated // server-side. void IAlchemiumExt.processCustomSchemeRequest(string uri, Dictionary<string, object> postData, ref string responseMimeType, ref string response) { // If we get a request for http://myExtension.com/ajax treat this as an an AJAX call if (uri.ToLower().EndsWith("ajax")) { // postData is passed in populated with the POST variables if the client did a AJAX POST // We could access those here if we wanted. It will be null if there were no POST variables if (postData != null) { foreach (var item in postData) { Debug.WriteLine("Passed in variable named: " + item.Key); } } responseMimeType = "application/json"; var responseObj = new SerializeTest(); responseObj.propertyOne = "Hello from c#!"; responseObj.propertyTwo = 42; // Need to respond with JSON so use the Alchemium API helper stringify() response = (string)_api.stringify(responseObj); } else { // For all other requests to our URI just return some HTML. // Alchemium does not require well formed HTML, so for this example we'll be lazy and just // spit a <div> and show an alert. Note how we are also referencing an // <a:include> tag. Alchemium will automatically inject the include's contents into // the reponse stream on our behalf. The only requirement is that the data-file referenced in the // include is in the [Path to Your app]\app\includes\*.* folder. response = "<a:include data-file='deps.html' /><div class='well'>" + "I will be rendered in the Alchemium browser in a twitter Bootstrap " + "well</div><script>alert('Back from c#!');</script>"; } } // Called whenever an element is clicked in the DOM // You recive the url of the active page, and target element id, name and html void IAlchemiumExt.DOMClick(string url, string id, string name, string elementHTML) { // Do something based on what the user clicked in the DOM } // Not used yet. For future use in Gallery/App store type scenarios. string IAlchemiumExt.description { get { return "My Extension"; } } // Not used yet. For future use in Gallery/App store type scenarios. string IAlchemiumExt.helpHTML { get { return "Help text here"; } } // Not used yet. For future use in Gallery/App store type scenarios. string IAlchemiumExt.name { get { return "My Extension"; } } } // Just a test object for serialization example public class SerializeTest { private string _propertyOne = ""; private double _propertyTwo = 0; public string propertyOne { get { return _propertyOne; } set { _propertyOne = value; } } public double propertyTwo { get { return _propertyTwo; } set { _propertyTwo = value; } } } }