UNPKG

kibana-with-account

Version:

kibana-with-account is develop based kibana project

142 lines (116 loc) 4.15 kB
define(function (require) { var angular = require('angular'); var _ = require('lodash'); var rison = require('ui/utils/rison'); // invokable/private angular dep return function ($location) { // feed in some of the private state from globalState return function (globalState, updateListeners, app) { var getAppStash = function (search) { var appStash = search._a && rison.decode(search._a); if (app.current) { // Apply the defaults to appStash appStash = _.defaults(appStash || {}, app.defaults); } return appStash; }; var diffTrans = function (trans) { var obj = trans[0]; var update = trans[1]; var diff = {}; // the keys that are currently set on obj, excluding methods var objKeys = Object.keys(obj).filter(function (key) { return typeof obj[key] !== 'function'; }); if (update) { // the keys obj should have after applying the update var updateKeys = diff.keys = Object.keys(update).filter(function (key) { return typeof update[key] !== 'function'; }); // the keys that will be removed diff.remove = _.difference(objKeys, updateKeys); // list of keys that will be added or changed diff.change = updateKeys.filter(function (key) { return !angular.equals(obj[key], update[key]); }); } else { diff.keys = objKeys.slice(0); diff.remove = []; diff.change = []; } // single list of all keys that are effected diff.all = [].concat(diff.remove, diff.change); return diff; }; var notify = function (trans, diff) { var listeners = null; if (trans[0] === app.current) { listeners = app.listeners; } else if (trans[0] === globalState) { listeners = updateListeners; } listeners && listeners.splice(0).forEach(function (defer) { defer.resolve(diff.all.slice(0)); }); }; var applyDiff = function (trans, diff) { if (!diff.all.length) return; var obj = trans[0]; var update = trans[1]; diff.remove.forEach(function (key) { delete obj[key]; }); diff.change.forEach(function (key) { obj[key] = update[key]; }); }; var syncTrans = function (trans, forceNotify) { // obj that will be modified by update(trans[1]) // if it is empty, we can skip it all var skipWrite = !trans[0]; trans[0] = trans[0] || {}; var diff = diffTrans(trans); if (!skipWrite && (forceNotify || diff.all.length)) { applyDiff(trans, diff); notify(trans, diff); } return diff; }; return { // sync by pushing to the url push: function (forceNotify) { var search = $location.search(); var appStash = getAppStash(search) || {}; var globalStash = search._g ? rison.decode(search._g) : {}; var res = _.mapValues({ app: [appStash, app.current], global: [globalStash, globalState] }, function (trans, key) { var diff = syncTrans(trans, forceNotify); var urlKey = '_' + key.charAt(0); if (diff.keys.length === 0) { delete search[urlKey]; } else { search[urlKey] = rison.encode(trans[0]); } return diff; }); $location.search(search); return res; }, // sync by pulling from the url pull: function (forceNotify) { var search = $location.search(); var appStash = getAppStash(search); var globalStash = search._g && rison.decode(search._g); return _.mapValues({ app: [app.current, appStash], global: [globalState, globalStash] }, function (trans) { return syncTrans(trans, forceNotify); }); } }; }; }; });