How does Stripe conceal data input by users into Stripe-element objects? - stripe-payments

var stripeElements = function (publicKey, setupIntent) {
var stripe = Stripe(publicKey);
var elements = stripe.elements();
// Element styles
var style = {
base: {
fontSize: '16px',
color: '#32325d',
fontFamily:
'-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, sans-serif',
fontSmoothing: 'antialiased',
'::placeholder': {
color: 'rgba(0,0,0,0.4)',
},
},
};
var card = elements.create('card', { style: style });
console.log(card); // returns a "t" object
card.mount('#card-element');
// Element focus ring
card.on('focus', function () {
var el = document.getElementById('card-element');
el.classList.add('focused');
});
card.on('blur', function () {
var el = document.getElementById('card-element');
el.classList.remove('focused');
});
// Handle payment submission when user clicks the pay button.
var button = document.getElementById('submit');
button.addEventListener('click', function (event) {
event.preventDefault();
changeLoadingState(true);
var email = document.getElementById('email').value;
stripe
.confirmCardSetup(setupIntent.client_secret, {
payment_method: {
card: card,
billing_details: { email: email },
},
})
.then(function (result) {
if (result.error) {
changeLoadingState(false);
var displayError = document.getElementById('card-errors');
displayError.textContent = result.error.message;
} else {
// The PaymentMethod was successfully set up
orderComplete(stripe, setupIntent.client_secret);
}
});
});
};
Stripe uses the above stripe.confirmCardSetup method to create a setupIntent object. This object can be used later to issue a charge.
In the above example, a Stripe "element" is used to create a "card" (the credit card) input. After I submit this info., this card-element gets attached to the object passed into the stripe.confirmCardSetup method, but when I attempt to console log the card object and find the CC data that was just input, I don't see it and I've been through every attribute.
How does Stripe conceal this info.?

Related

Creating and Capturing payment with paypal v2 node.js

I am trying to integrate PayPal server-side payment on a website with a new v2 since v1 is deprecated. Since I had to include quite a lot of code from their git, i will post here everything for a working example
In v1 i could do it really easily:
app.get('/create', function (req, res) {
//build PayPal payment request
let payReq = JSON.stringify({
'intent': 'sale',
'redirect_urls': {
'return_url': 'http://localhost:8081/process',
'cancel_url': 'http://localhost:8081/cancel'
},
'payer': {
'payment_method': 'paypal'
},
'transactions': [{
'amount': {
'total': '7.47',
'currency': 'USD'
},
'description': 'This is the payment transaction description.'
}]
});
paypal.payment.create(payReq, function (error, payment) {
if (error) {
console.error(error);
} else {
//capture HATEOAS links
let links = {};
payment.links.forEach(function (linkObj) {
links[linkObj.rel] = {
'href': linkObj.href,
'method': linkObj.method
};
})
//if redirect url present, redirect user
if (links.hasOwnProperty('approval_url')) {
res.redirect(links['approval_url'].href);
} else {
console.error('no redirect URI present');
}
}
});
});
app.get('/process', function (req, res) {
let paymentId = req.query.paymentId;
let payerId = {'payer_id': req.query.PayerID};
paypal.payment.execute(paymentId, payerId, function (error, payment) {
if (error) {
console.error(error);
} else {
if (payment.state == 'approved') {
const payerCountry = payment.payer.payer_info.country_code;
const total = payment.transactions[0].amount.total;
const currency = payment.transactions[0].amount.currency;
savePayment(payerCountry, total, currency);
res.send('payment completed successfully ' + cnt++);
} else {
res.send('payment not successful');
}
}
});
});
The create endpoint basically creates the order, the paypal API returns hateos links and the controller says the browser should redirect to that link. Once redirected , if user approves payment on paypal site he is redirected to on of
'redirect_urls': {
'return_url': 'http://localhost:8081/process',
'cancel_url': 'http://localhost:8081/cancel'
},
process endpoints retrieves PAYMENT ID and PAYER ID from query and captures the order - allowing me to do whatever i want to do ( e.g save payment in db ) in callback.
Now v2 seems like huge mess:
Following devs guide i have created
Paypal button (copy paste ):
import React, {useEffect} from "react";
import {PayPalButtons, PayPalScriptProvider, usePayPalScriptReducer} from "#paypal/react-paypal-js";
// This values are the props in the UI
const amount = "2";
const currency = "USD";
const style = {"layout": "vertical"};
const ButtonWrapper = ({currency, showSpinner}) => {
// usePayPalScriptReducer can be use only inside children of PayPalScriptProviders
// This is the main reason to wrap the PayPalButtons in a new component
const [{options, isPending}, dispatch] = usePayPalScriptReducer();
useEffect(() => {
dispatch({
type: "resetOptions",
value: {
...options,
currency: currency,
},
});
}, [currency, showSpinner]);
const createOrder = (data, actions) => {
console.log("create")
return fetch('http://localhost:8081/create', {
method: 'post'
}).then(function (res) {
return res.json();
}).then(function (orderData) {
console.log(orderData);
window.location = orderData.redirect;
});
}
// Call your server to finalize the transaction
const onApprove = (data, actions) => {
console.log("approve")
return fetch('/process', {
method: 'post'
}).then(function (res) {
return res.json();
}).then(function (orderData) {
// Three cases to handle:
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
// (2) Other non-recoverable errors -> Show a failure message
// (3) Successful transaction -> Show confirmation or thank you
// This example reads a v2/checkout/orders capture response, propagated from the server
// You could use a different API or structure for your 'orderData'
var errorDetail = Array.isArray(orderData.details) && orderData.details[0];
if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') {
return actions.restart(); // Recoverable state, per:
// https://developer.paypal.com/docs/checkout/integration-features/funding-failure/
}
if (errorDetail) {
var msg = 'Sorry, your transaction could not be processed.';
if (errorDetail.description) msg += '\n\n' + errorDetail.description;
if (orderData.debug_id) msg += ' (' + orderData.debug_id + ')';
return alert(msg); // Show a failure message (try to avoid alerts in production environments)
}
// Successful capture! For demo purposes:
console.log('Capture result', orderData, JSON.stringify(orderData, null, 2));
var transaction = orderData.purchase_units[0].payments.captures[0];
alert('Transaction ' + transaction.status + ': ' + transaction.id + '\n\nSee console for all available details');
});
}
return (<>
{(showSpinner && isPending) && <div className="spinner"/>}
<PayPalButtons
style={style}
disabled={false}
forceReRender={[amount, currency, style]}
fundingSource={undefined}
createOrder={(data, actions) => createOrder(data, actions)}
onApprove={(data, actions) => onApprove(data, actions)}
/>
</>
);
}
export default function PayPalButton() {
return (
<div style={{ maxWidth: "750px", minHeight: "200px" }}>
<PayPalScriptProvider
options={{
"client-id": "test",
components: "buttons",
currency: "USD"
}}
>
<ButtonWrapper
currency={currency}
showSpinner={false}
/>
</PayPalScriptProvider>
</div>
);
}
And then followed the flow from paypal's github example
created their HttpClient
const checkoutNodeJssdk = require('#paypal/checkout-server-sdk');
/**
* Returns PayPal HTTP client instance with environment which has access
* credentials context. This can be used invoke PayPal API's provided the
* credentials have the access to do so.
*/
function client() {
return new checkoutNodeJssdk.core.PayPalHttpClient(environment());
}
/**
* Setting up and Returns PayPal SDK environment with PayPal Access credentials.
* For demo purpose, we are using SandboxEnvironment. In production this will be
* LiveEnvironment.
*/
function environment() {
let clientId = process.env.PAYPAL_CLIENT_ID || '<clientId>';
let clientSecret = process.env.PAYPAL_CLIENT_SECRET || '<secret>';
if (process.env.NODE_ENV === 'production') {
return new checkoutNodeJssdk.core.LiveEnvironment(clientId, clientSecret);
}
return new checkoutNodeJssdk.core.SandboxEnvironment(clientId, clientSecret);
}
async function prettyPrint(jsonData, pre=""){
let pretty = "";
function capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
}
for (let key in jsonData){
if (jsonData.hasOwnProperty(key)){
if (isNaN(key))
pretty += pre + capitalize(key) + ": ";
else
pretty += pre + (parseInt(key) + 1) + ": ";
if (typeof jsonData[key] === "object"){
pretty += "\n";
pretty += await prettyPrint(jsonData[key], pre + "\t");
}
else {
pretty += jsonData[key] + "\n";
}
}
}
return pretty;
}
module.exports = {client: client, prettyPrint:prettyPrint};
created their CreateOrder:
/**
* PayPal SDK dependency
*/
const checkoutNodeJssdk = require('#paypal/checkout-server-sdk');
/**
* PayPal HTTP client dependency
*/
const payPalClient = require('./PayPalClient');
/**
* Setting up the JSON request body for creating the Order. The Intent in the
* request body should be set as "CAPTURE" for capture intent flow.
*
*/
function buildRequestBody() {
return {
"intent": "CAPTURE",
"application_context": {
"return_url": "http://localhost:8081/process",
"cancel_url": "https://www.example.com",
"locale": "en-US",
"landing_page": "BILLING",
"user_action": "CONTINUE"
},
"purchase_units": [
{
"soft_descriptor": "Donation",
"amount": {
"currency_code": "USD",
"value": "220.00"
}
}
]
};
}
/**
* This is the sample function which can be sued to create an order. It uses the
* JSON body returned by buildRequestBody() to create an new Order.
*/
async function createOrder(debug=false) {
try {
const request = new checkoutNodeJssdk.orders.OrdersCreateRequest();
request.headers["prefer"] = "return=representation";
request.requestBody(buildRequestBody());
const response = await payPalClient.client().execute(request);
if (debug){
console.log("Status Code: " + response.statusCode);
console.log("Status: " + response.result.status);
console.log("Order ID: " + response.result.id);
console.log("Intent: " + response.result.intent);
console.log("Links: ");
response.result.links.forEach((item, index) => {
let rel = item.rel;
let href = item.href;
let method = item.method;
let message = `\t${rel}: ${href}\tCall Type: ${method}`;
console.log(message);
});
console.log(`Gross Amount: ${response.result.purchase_units[0].amount.currency_code} ${response.result.purchase_units[0].amount.value}`);
// To toggle print the whole body comment/uncomment the below line
console.log(JSON.stringify(response.result, null, 4));
}
return response;
}
catch (e) {
console.log(e)
}
}
/**
* This is the driver function which invokes the createOrder function to create
* an sample order.
*/
if (require.main === module){
(async() => await createOrder(true))();
}
/**
* Exports the Create Order function. If needed this can be invoked from the
* order modules to execute the end to flow like create order, retrieve, capture
* and refund(Optional)
*/
module.exports = {createOrder:createOrder};
And endpoints:
const createUsersOrder = async (res) => {
try {
let response = await createOrder();
console.log("Creating Order...");
let orderId = "";
if (response.statusCode === 201){
console.log("Created Successfully");
orderId = response.result.id;
console.log("Links:");
response.result.links.forEach((item, index) => {
let rel = item.rel;
let href = item.href;
let method = item.method;
let message = `\t${rel}: ${href}\tCall Type: ${method}`;
console.log(message);
});
let links = {};
response.result.links.forEach(function (linkObj) {
links[linkObj.rel] = {
'href': linkObj.href,
'method': linkObj.method
};
})
//if redirect url present, redirect user
if (links.hasOwnProperty('approve')) {
var returnObj = {redirect : links['approve'].href}
console.log("Returning " + returnObj)
res.send(returnObj);
} else {
console.error('no redirect URI present');
}
}
console.log("Copy approve link and paste it in browser. Login with buyer account and follow the instructions.\nOnce approved hit enter...");
return
} catch (error) {
console.log('There was an error: ', error);
}
};
app.post("/create", function(req,res) {
createUsersOrder(res);
})
Here, this is called when button is clicked, as "createOrder" method is called. I create order just like in the v1 code, and then redirect browser to the url. However when the user approves transaction on paypal, and thus is being redirected to one of
"application_context": {
"return_url": "http://localhost:8081/process",
"cancel_url": "http://localhost:8081/cancel",
"locale": "en-US",
"landing_page": "BILLING",
"user_action": "CONTINUE"
},
return url ( /process route for success ), the request DOES NOT contain payment_id, only PAYER_ID. But the payment_id ( or order_id in v2 ) is needed to capture the order.
Since i have found literally zero blogs, tutorials, guide for v2 ( only millions for v1) i am confused where to get the order id. Do i really need to save it in DB after i create the order? OR is there any other trick?
Also, the button contains onApprove method, but after creating order, the browser is redirected to paypal, and the paypal redirects user to http://localhost:8081/process endpoint - thus the onApprove method is never invoked and useless (?).
This whole flow of v2 is really confusing, is there something i am missing?
Thanks for help
With your v2 code, do not use any redirects. At all. Your button should call 2 endpoints on your server. These two endpoints should (respectively) do the API operations of creating and capturing the order, and return the JSON result in each case (the capture route can do any server-side operations like storing the transaction result in the database before forwarding the JSON result to the client caller, since the client needs to handle any capture error situations as well as showing a success message). You can find a full stack node.js example in the PayPal integration guide, but it's fine to keep your #paypal/react-paypal-js code pretty much as-is for the front end.

How to access Stripe token from form POST submission in Python?

I'm using pretty much the standard Stripe code to obtain a token which I can see from the console is successful and then I am passing that in a hidden input form field to my Python app.
I can return the data from the form but don't know how to access the token ID and other data from the object. I want to access the data within "stripe-token-return [object Object]"
My Python code is :
#app.route('/newForm', methods=['POST', 'GET'])
def newForm():
if request.method == 'POST':
formData = request.values
for key, value in formData.items():
print(key, value)
token = request.form['stripe-token-return']
print(token)
Here is the broadly standard Stripe code which I can see is successfully getting the token when I log to the console.
<script type="text/javascript">
// Create a Stripe client.
var stripe = Stripe('{{ key }}');
// Create an instance of Elements.
var elements = stripe.elements();
// Custom styling can be passed to options when creating an Element.
// (Note that this demo uses a wider set of styles than the guide below.)
var style = {
base: {
color: '#32325d',
lineHeight: '18px',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
// Create an instance of the card Element.
var card = elements.create('card', {
style: style
});
// Add an instance of the card Element into the `card-element` <div>.
card.mount('#card-element');
// Handle real-time validation errors from the card Element.
card.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
// Handle form submission.
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
event.preventDefault();
stripe.createToken(card).then(function(result) {
if (result.error) {
// Inform the user if there was an error.
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
// Send the token to your server.
// form.append($('<input type="hidden" name="stripeToken">').val(result.token.id));
console.log(result.token);
document.getElementById('stripe-token-return').value = result.token;
form.submit();
}
});
});
</script>
You want to use:
document.getElementById('stripe-token-return').value = result.token.id;
Instead; right now it's sending the whole object, not just the ID.

Creating form in netsuite using suitscript 2.0

var formData = new FormData();
formData.append("name", "John");
formData.append("age", "31");
for (var value of formData.values()) {
log.debug(value);
}
but when i want to log form values using formData api. It's giving below error.
ReferenceError: "FormData" is not defined.
FormData is a client side API managed under XMHttpRequest
UserEvent scripts are server side scripts with no browser based APIs available at all.
So you could use FormData in a client script to send info to a Suitelet or RESTlet but it's not present in a UserEvent script.
If you want to create a form in a Suitelet using SS2.0 you can use the following as a sample:
/**
*#NApiVersion 2.x
*#NScriptType Suitelet
*/
define(["N/log", "N/redirect", "N/runtime", "N/ui/serverWidget", "N/url", "./kotnRECBCFilters"],
function (log, redirect, runtime, ui, url, kotnRECBCFilters_1) {
function showPropertiesForm(context) {
var form = ui.createForm({
title: 'Property Trust Ledger'
});
var req = context.request;
var fromLoc = form.addField({
id: 'custpage_loc',
type: ui.FieldType.SELECT,
label: 'For Property',
source: 'location'
});
fromLoc.updateLayoutType({ layoutType: ui.FieldLayoutType.NORMAL });
fromLoc.updateBreakType({ breakType: ui.FieldBreakType.STARTCOL });
if (req.parameters.custpage_loc) {
fromLoc.defaultValue = req.parameters.custpage_loc;
}
var notAfterDate = form.addField({
id: 'custpage_not_after',
type: ui.FieldType.DATE,
label: 'On or Before'
});
if (req.parameters.custpage_not_after) {
notAfterDate.defaultValue = req.parameters.custpage_not_after;
}
form.addSubmitButton({
label: 'Get Detail'
});
//... bunch of stuff removed
context.response.writePage(form);
}
function onRequest(context) {
if (context.request.method === 'POST') {
var currentScript = runtime.getCurrentScript();
var params = {};
for (var k in context.request.parameters) {
if (k.indexOf('custpage_') == 0 && k.indexOf('custpage_transactions') == -1) {
if ((/^custpage_.*_display$/).test(k))
continue;
params[k] = context.request.parameters[k];
}
}
redirect.toSuitelet({
scriptId: currentScript.id,
deploymentId: currentScript.deploymentId,
parameters: params
});
return;
}
showPropertiesForm(context);
}
exports.onRequest = onRequest;
});

Use Socket.io to fill google Area Chart - 'google.visualization.DataTable is not a constructor'

I use NodeJS and Socket.io to get data from a database. I now want to fill a google area chart with these data but i kind of fail at doing it.
The data is transmitted as Objects. Each Object contains two values (datetime and value). I append these values to an array and then store them in a DataTable:
google.load('visualization', '1', {
packages: ['corechart']
});
google.setOnLoadCallback(drawChart);
var socket = io();
getData();
function drawChart(dataArray) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'DateTime');
data.addColumn('number', 'Value');
for (var i = 0; i < dataArray.length; i += 2) {
console.log(dataArray[0]);
data.addRow([dataArray[i], dataArray[i + 1]]);
}
var chart = new google.visualization.AreaChart(document.getElementById('chart'));
chart.draw(data, {
title: "Data Visualization",
isStacked: true,
width: '50%',
height: '50%',
vAxis: {
title: 'Data v-Axis'
},
hAxis: {
title: 'Data h-Axis'
}
})
}
function getData() {
socket.emit('GET');
socket.on('serverSent', function (data) {
var processedData = processData(data);
drawChart(processedData);
})
}
function processData(data) {
var arr = new Array();
jQuery.each(data, function (index, object) {
arr.push(object['datetime'], parseInt(object['value']));
})
return arr;
}
If i call my website i see the chart but without any values and the error message `google.visualization.DataTable is not a constructor´. So what am i doing wrong?
The problem is drawChart is being called twice.
From both google.setOnLoadCallback and getData.
If getData is called before google.setOnLoadCallback,
then google.visualization.DataTable will not be recognized.
In addition, it is recommended to use loader.js vs. jsapi.
See Load the Libraries for more info...
As such, please try the following...
Replace...
<script src="https://www.google.com/jsapi"></script>
With...
<script src="https://www.gstatic.com/charts/loader.js"></script>
And try something like...
google.charts.load('current', {
callback: init,
packages: ['corechart']
});
function init() {
var socket = io();
socket.emit('GET');
socket.on('serverSent', function (data) {
var processedData = processData(data);
drawChart(processedData);
});
}
function drawChart(dataArray) {
var data = new google.visualization.DataTable();
data.addColumn('string', 'DateTime');
data.addColumn('number', 'Value');
for (var i = 0; i < dataArray.length; i += 2) {
console.log(dataArray[0]);
data.addRow([dataArray[i], dataArray[i + 1]]);
}
var chart = new google.visualization.AreaChart(document.getElementById('chart'));
chart.draw(data, {
title: "Data Visualization",
isStacked: true,
width: '50%',
height: '50%',
vAxis: {
title: 'Data v-Axis'
},
hAxis: {
title: 'Data h-Axis'
}
})
}

Save and Restore rectangles with connections in Draw2D.js touch via JSON

How do I create rectangles with 4 ports (each side) in a correct way, so I can save and restore them via JSON?
I tried this one, but only the rectangles are been saved. The connections and labels got lost.
JSFiddle: http://jsfiddle.net/xfvf4/36/
Create two elements (Add) - move them and connect them
Write: This gives the content as JSON-Array
Read: Should make the grafic out of the JSON-Array
The last point doesn't work.
JS:
var LabelRectangle = draw2d.shape.basic.Rectangle.extend({
NAME: "draw2d.shape.basic.Rectangle",
init: function (attr) {
this._super(attr);
this.label = new draw2d.shape.basic.Label({
text: "Text",
fontColor: "#0d0d0d",
stroke: 0
});
this.add(this.label, new draw2d.layout.locator.CenterLocator(this));
this.label.installEditor(new draw2d.ui.LabelInplaceEditor());
this.createPort("hybrid", new draw2d.layout.locator.BottomLocator(this));
},
getPersistentAttributes: function () {
var memento = this._super();
memento.labels = [];
var ports = [];
ports = this.getPorts();
memento.ports = [];
console.log(ports);
this.children.each(function (i, e) {
console.log(e);
memento.labels.push({
id: e.figure.getId(),
label: e.figure.getText(),
locator: e.locator.NAME
});
ports.each(function (i, e) {
memento.ports.push({
//id: e.id,
name: e.name,
locator: e.locator.NAME
});
});
});
return memento;
},
setPersistentAttributes: function (memento) {
this._super(memento);
this.resetChildren();
$.each(memento.labels, $.proxy(function (i, e) {
var label = new draw2d.shape.basic.Label(e.label);
var locator = eval("new " + e.locator + "()");
locator.setParent(this);
this.add(label, locator);
}, this));
}
});
$(window).load(function () {
var canvas = new draw2d.Canvas("gfx_holder");
$("#add").click(function (e) { // Add a new rectangle
var rect = new LabelRectangle({
width: 200,
height: 40,
radius: 3,
bgColor: '#ffffff',
stroke: 0
});
rect.createPort("hybrid", new draw2d.layout.locator.OutputPortLocator(rect));
rect.createPort("hybrid", new draw2d.layout.locator.InputPortLocator(rect));
rect.createPort("hybrid", new draw2d.layout.locator.TopLocator(rect));
canvas.add(rect, 150, 200);
});
$("#write").click(function (e) { // Write to pre-Element (JSON)
var writer = new draw2d.io.json.Writer();
writer.marshal(canvas, function(json){
$("#json").text(JSON.stringify(json,null,2));
$('#gfx_holder').empty();
});
});
$("#read").click(function (e) { // Read from pre-Element (JSON)
var canvas = new draw2d.Canvas("gfx_holder");
var jsonDocument = $('#json').text();
var reader = new draw2d.io.json.Reader();
reader.unmarshal(canvas, jsonDocument);
});
});
HTML:
<ul class="toolbar">
<li>Add</li>
<li>Write</li>
<li>Read</li>
</ul>
<div id="container" class="boxed">
<div onselectstart="javascript:/*IE8 hack*/return false" id="gfx_holder" style="width:100%; height:100%; ">
</div>
<pre id="json" style="overflow:auto;position:absolute; top:10px; right:10px; width:350; height:500;background:white;border:1px solid gray">
</pre>
</div>
Just use the write.js and Reader.js in the "json"-Folder of Draw2D.js 5.0.4 and this code:
$(window).load(function () {
var canvas = new draw2d.Canvas("gfx_holder");
// unmarshal the JSON document into the canvas
// (load)
var reader = new draw2d.io.json.Reader();
reader.unmarshal(canvas, jsonDocument);
// display the JSON document in the preview DIV
//
displayJSON(canvas);
// add an event listener to the Canvas for change notifications.
// We just dump the current canvas document into the DIV
//
canvas.getCommandStack().addEventListener(function(e){
if(e.isPostChangeEvent()){
displayJSON(canvas);
}
});
});
function displayJSON(canvas){
var writer = new draw2d.io.json.Writer();
writer.marshal(canvas,function(json){
$("#json").text(JSON.stringify(json, null, 2));
});
}
This should work:
var LabelRectangle = draw2d.shape.basic.Rectangle.extend({
NAME: "draw2d.shape.basic.Rectangle",
init: function (attr) {
this._super(attr);
this.label = new draw2d.shape.basic.Label({
text: "Text",
fontColor: "#0d0d0d",
stroke: 0
});
this.add(this.label, new draw2d.layout.locator.CenterLocator(this));
this.label.installEditor(new draw2d.ui.LabelInplaceEditor());
},
getPersistentAttributes: function () {
var memento = this._super();
memento.labels = [];
memento.ports = [];
this.getPorts().each(function(i,port){
memento.ports.push({
name : port.getName(),
port : port.NAME,
locator: port.getLocator().NAME
});
});
this.children.each(function (i, e) {
memento.labels.push({
id: e.figure.getId(),
label: e.figure.getText(),
locator: e.locator.NAME
});
});
return memento;
},
setPersistentAttributes: function (memento) {
this._super(memento);
this.resetChildren();
if(typeof memento.ports !=="undefined"){
this.resetPorts();
$.each(memento.ports, $.proxy(function(i,e){
var port = eval("new "+e.port+"()");
var locator = eval("new "+e.locator+"()");
this.add(port, locator);
port.setName(e.name);
},this));
}
$.each(memento.labels, $.proxy(function (i, e) {
var label = new draw2d.shape.basic.Label(e.label);
var locator = eval("new " + e.locator + "()");
locator.setParent(this);
this.add(label, locator);
}, this));
}
});

Resources