thingsboard-aplcache
Changes
ui/package.json 1(+1 -0)
ui/src/app/common/utf8-support.js 138(+138 -0)
ui/src/app/common/utils.service.js 27(+23 -4)
Details
ui/package.json 1(+1 -0)
diff --git a/ui/package.json b/ui/package.json
index 45f2f4b..b4485dc 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -45,6 +45,7 @@
"angular-ui-ace": "^0.2.3",
"angular-ui-router": "^0.3.1",
"angular-websocket": "^2.0.1",
+ "base64-js": "^1.2.1",
"brace": "^0.8.0",
"canvas-gauges": "^2.0.9",
"clipboard": "^1.5.15",
ui/src/app/common/utf8-support.js 138(+138 -0)
diff --git a/ui/src/app/common/utf8-support.js b/ui/src/app/common/utf8-support.js
new file mode 100644
index 0000000..464fa40
--- /dev/null
+++ b/ui/src/app/common/utf8-support.js
@@ -0,0 +1,138 @@
+/*
+ * Copyright © 2016-2017 The Thingsboard Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export function utf8Encode(str) {
+ var result;
+
+ if (angular.isUndefined(Uint8Array)) { // eslint-disable-line no-undef
+ result = utf8ToBytes(str);
+ } else {
+ result = new Uint8Array(utf8ToBytes(str)); // eslint-disable-line no-undef
+ }
+
+ return result;
+}
+
+export function utf8Decode(bytes) {
+ return utf8Slice(bytes, 0, bytes.length);
+}
+
+function utf8Slice (buf, start, end) {
+ var res = ''
+ var tmp = ''
+ end = Math.min(buf.length, end || Infinity)
+ start = start || 0;
+
+ for (var i = start; i < end; i++) {
+ if (buf[i] <= 0x7F) {
+ res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i])
+ tmp = ''
+ } else {
+ tmp += '%' + buf[i].toString(16)
+ }
+ }
+
+ return res + decodeUtf8Char(tmp)
+}
+
+function decodeUtf8Char (str) {
+ try {
+ return decodeURIComponent(str)
+ } catch (err) {
+ return String.fromCharCode(0xFFFD) // UTF 8 invalid char
+ }
+}
+
+function utf8ToBytes (string, units) {
+ units = units || Infinity
+ var codePoint
+ var length = string.length
+ var leadSurrogate = null
+ var bytes = []
+ var i = 0
+
+ for (; i < length; i++) {
+ codePoint = string.charCodeAt(i)
+
+ // is surrogate component
+ if (codePoint > 0xD7FF && codePoint < 0xE000) {
+ // last char was a lead
+ if (leadSurrogate) {
+ // 2 leads in a row
+ if (codePoint < 0xDC00) {
+ if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+ leadSurrogate = codePoint
+ continue
+ } else {
+ // valid surrogate pair
+ codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000
+ leadSurrogate = null
+ }
+ } else {
+ // no lead yet
+
+ if (codePoint > 0xDBFF) {
+ // unexpected trail
+ if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+ continue
+ } else if (i + 1 === length) {
+ // unpaired lead
+ if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+ continue
+ } else {
+ // valid lead
+ leadSurrogate = codePoint
+ continue
+ }
+ }
+ } else if (leadSurrogate) {
+ // valid bmp char, but last char was a lead
+ if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+ leadSurrogate = null
+ }
+
+ // encode utf8
+ if (codePoint < 0x80) {
+ if ((units -= 1) < 0) break
+ bytes.push(codePoint)
+ } else if (codePoint < 0x800) {
+ if ((units -= 2) < 0) break
+ bytes.push(
+ codePoint >> 0x6 | 0xC0,
+ codePoint & 0x3F | 0x80
+ )
+ } else if (codePoint < 0x10000) {
+ if ((units -= 3) < 0) break
+ bytes.push(
+ codePoint >> 0xC | 0xE0,
+ codePoint >> 0x6 & 0x3F | 0x80,
+ codePoint & 0x3F | 0x80
+ )
+ } else if (codePoint < 0x200000) {
+ if ((units -= 4) < 0) break
+ bytes.push(
+ codePoint >> 0x12 | 0xF0,
+ codePoint >> 0xC & 0x3F | 0x80,
+ codePoint >> 0x6 & 0x3F | 0x80,
+ codePoint & 0x3F | 0x80
+ )
+ } else {
+ throw new Error('Invalid code point')
+ }
+ }
+
+ return bytes
+}
\ No newline at end of file
ui/src/app/common/utils.service.js 27(+23 -4)
diff --git a/ui/src/app/common/utils.service.js b/ui/src/app/common/utils.service.js
index 7c9f97d..61d4d81 100644
--- a/ui/src/app/common/utils.service.js
+++ b/ui/src/app/common/utils.service.js
@@ -20,9 +20,12 @@ import materialIconsCodepoints from 'raw-loader!material-design-icons/iconfont/c
/* eslint-enable import/no-unresolved, import/default */
-import tinycolor from "tinycolor2";
-import jsonSchemaDefaults from "json-schema-defaults";
-import thingsboardTypes from "./types.constant";
+import tinycolor from 'tinycolor2';
+import jsonSchemaDefaults from 'json-schema-defaults';
+import base64js from 'base64-js';
+import {utf8Encode, utf8Decode} from './utf8-support';
+
+import thingsboardTypes from './types.constant';
export default angular.module('thingsboard.utils', [thingsboardTypes])
.factory('utils', Utils)
@@ -153,7 +156,9 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, $q, $timeout, t
createKey: createKey,
createLabelFromDatasource: createLabelFromDatasource,
insertVariable: insertVariable,
- customTranslation: customTranslation
+ customTranslation: customTranslation,
+ objToBase64: objToBase64,
+ base64toObj: base64toObj
}
return service;
@@ -486,4 +491,18 @@ function Utils($mdColorPalette, $rootScope, $window, $translate, $q, $timeout, t
return result;
}
+ function objToBase64(obj) {
+ var json = angular.toJson(obj);
+ var encoded = utf8Encode(json);
+ var b64Encoded = base64js.fromByteArray(encoded);
+ return b64Encoded;
+ }
+
+ function base64toObj(b64Encoded) {
+ var encoded = base64js.toByteArray(b64Encoded);
+ var json = utf8Decode(encoded);
+ var obj = angular.fromJson(json);
+ return obj;
+ }
+
}
diff --git a/ui/src/app/components/widget/widget.controller.js b/ui/src/app/components/widget/widget.controller.js
index 4e85718..7ed79ae 100644
--- a/ui/src/app/components/widget/widget.controller.js
+++ b/ui/src/app/components/widget/widget.controller.js
@@ -473,7 +473,7 @@ export default function WidgetController($scope, $state, $timeout, $window, $ele
}
var stateParams = {
dashboardId: targetDashboardId,
- state: angular.toJson([ stateObject ])
+ state: utils.objToBase64([ stateObject ])
}
$state.go('home.dashboards.dashboard', stateParams);
break;
diff --git a/ui/src/app/dashboard/states/default-state-controller.js b/ui/src/app/dashboard/states/default-state-controller.js
index ae92d37..7d810ca 100644
--- a/ui/src/app/dashboard/states/default-state-controller.js
+++ b/ui/src/app/dashboard/states/default-state-controller.js
@@ -121,11 +121,11 @@ export default function DefaultStateController($scope, $location, $state, $state
return utils.customTranslation(state.name, id);
}
- function parseState(stateJson) {
+ function parseState(stateBase64) {
var result;
- if (stateJson) {
+ if (stateBase64) {
try {
- result = angular.fromJson(stateJson);
+ result = utils.base64toObj(stateBase64);
} catch (e) {
result = [ { id: null, params: {} } ];
}
@@ -205,7 +205,7 @@ export default function DefaultStateController($scope, $location, $state, $state
function updateLocation() {
if (vm.stateObject[0].id) {
- $location.search({state : angular.toJson(vm.stateObject)});
+ $location.search({state : utils.objToBase64(vm.stateObject)});
}
}
}
diff --git a/ui/src/app/dashboard/states/entity-state-controller.js b/ui/src/app/dashboard/states/entity-state-controller.js
index cbe91fa..a554adf 100644
--- a/ui/src/app/dashboard/states/entity-state-controller.js
+++ b/ui/src/app/dashboard/states/entity-state-controller.js
@@ -168,11 +168,11 @@ export default function EntityStateController($scope, $location, $state, $stateP
return deferred.promise;
}
- function parseState(stateJson) {
+ function parseState(stateBase64) {
var result;
- if (stateJson) {
+ if (stateBase64) {
try {
- result = angular.fromJson(stateJson);
+ result = utils.base64toObj(stateBase64);
} catch (e) {
result = [ { id: null, params: {} } ];
}
@@ -278,7 +278,7 @@ export default function EntityStateController($scope, $location, $state, $stateP
function updateLocation() {
if (vm.stateObject[vm.stateObject.length-1].id) {
- $location.search({state : angular.toJson(vm.stateObject)});
+ $location.search({state : utils.objToBase64(vm.stateObject)});
}
}
diff --git a/ui/src/app/entity/attribute/add-widget-to-dashboard-dialog.controller.js b/ui/src/app/entity/attribute/add-widget-to-dashboard-dialog.controller.js
index a133829..64726db 100644
--- a/ui/src/app/entity/attribute/add-widget-to-dashboard-dialog.controller.js
+++ b/ui/src/app/entity/attribute/add-widget-to-dashboard-dialog.controller.js
@@ -23,7 +23,7 @@ import selectTargetLayoutTemplate from '../../dashboard/layouts/select-target-la
/*@ngInject*/
export default function AddWidgetToDashboardDialogController($scope, $mdDialog, $state, $q, $document, dashboardUtils,
- types, itembuffer, dashboardService, entityId, entityType, entityName, widget) {
+ utils, types, itembuffer, dashboardService, entityId, entityType, entityName, widget) {
var vm = this;
@@ -143,7 +143,7 @@ export default function AddWidgetToDashboardDialogController($scope, $mdDialog,
var stateIds = Object.keys(dashboard.configuration.states);
var stateIndex = stateIds.indexOf(targetState);
if (stateIndex > 0) {
- stateParams.state = angular.toJson([ {id: targetState, params: {}} ]);
+ stateParams.state = utils.objToBase64([ {id: targetState, params: {}} ]);
}
$state.go('home.dashboards.dashboard', stateParams);
}