Browse Source

Merge pull request #216 from Telaxus/webpack

Introduce webpack
experimental
Paweł Jedwabny 4 years ago
committed by GitHub
parent
commit
bf23b21d4c
17 changed files with 852 additions and 12624 deletions
  1. +4
    -0
      .babelrc
  2. +0
    -2
      composer.json
  3. +0
    -0
      dist/.gitkeep
  4. +0
    -307
      include/epesi.js
  5. +2
    -20
      index.php
  6. +0
    -12269
      libs/Chart.js
  7. +0
    -4
      libs/HistoryKeeper.js
  8. +72
    -0
      libs/HistoryKeeper/EventManager.js
  9. +272
    -0
      libs/HistoryKeeper/History.js
  10. +0
    -7
      libs/jquery-ui-1.12.1.custom.min.css
  11. +0
    -9
      libs/jquery-ui-1.12.1.custom.min.js
  12. +0
    -6
      libs/jquery-ui.txt
  13. +52
    -0
      package.json
  14. +233
    -0
      src/epesi.js
  15. +67
    -0
      src/index.js
  16. +105
    -0
      src/loader.js
  17. +45
    -0
      webpack.config.js

+ 4
- 0
.babelrc View File

@@ -0,0 +1,4 @@
{
"presets": ["env"],
"plugins": ["transform-runtime"]
}

+ 0
- 2
composer.json View File

@@ -11,9 +11,7 @@
"memio/memio": "^1.0",
"psy/psysh": "@stable",
"anahkiasen/underscore-php": "^2.0",
"bower-asset/gentelella": "*",
"moneyphp/money": "^3.0",
"nnnick/chartjs": "^2.5",
"enyo/dropzone": "@stable",
"ezyang/htmlpurifier": "^4.9"
},


+ 0
- 0
dist/.gitkeep View File


+ 0
- 307
include/epesi.js View File

@@ -1,307 +0,0 @@
/*
* @author Paul Bukowski <pbukowski@telaxus.com>
* @version 1.0
* @copyright Copyright &copy; 2007, Telaxus LLC
* @licence MIT
*/

function focus_by_id(idd) {
xx = document.getElementById(idd);
if(xx) setTimeout(function(){jq(xx).focus();},200);
};

function addslashes(x){return x.replace(/('|"|\\)/g,"\\$1")}

function wait_while_null(id,action) {
if(eval('typeof('+id+')') != 'undefined')
eval(action);
else
setTimeout('wait_while_null(\''+addslashes(id)+'\', \''+addslashes(action)+'\')',200);
};

var Epesi = {
default_indicator:'loading...',
procOn:0,
client_id:0,
process_file:'process.php',
indicator:'epesiStatus',
indicator_text:'epesiStatusText',
confirmLeave: {
// object of form ids which require confirmation for leaving the page
// store changed fields to pass through submit state
forms:{},
// store currently submitted form. If it'll fail to validate then we
// have list of changed fields
forms_freezed:{},
message:'Leave page?',
//checks if leaving the page is approved
check: function() {
//remove non-existent forms from the array
jQuery.each(this.forms, function(f) {
if (!jQuery('#'+f).length) Epesi.confirmLeave.deactivate(f);
});
jQuery.each(this.forms_freezed, function(f) {
if (!jQuery('#'+f).length) Epesi.confirmLeave.deactivate(f);
});
//check if there is any not freezed form with changed values to confirm leave
var requires_confirmation = false;
if (Object.keys(this.forms).length) {
for (var form in this.forms) {
if (jQuery('#' + form + ' .changed-input').length) {
requires_confirmation = true;
break;
}
}
}
if (requires_confirmation) {
//take care if user disabled alert messages
var openTime = new Date();
try {
var confirmed = confirm(this.message);
} catch(e) {
var confirmed = true;
}
var closeTime = new Date();
if ((closeTime - openTime) > 350 && !confirmed) return false;
this.deactivate();
}
return true;
},
activate: function(f, m) {
this.message = m;
// add form or restore from freezed state - form is freezed for submit
if (!(f in this.forms)) {
if (f in this.forms_freezed) {
this.forms[f] = this.forms_freezed[f];
delete this.forms_freezed[f];
} else {
this.forms[f] = {};
}
}
// apply class to all changed inputs - required for validation failure
for (var key in this.forms[f]) {
jQuery('#' + f + ' [name="' + key + '"]').addClass('changed-input');
}
// on change add changed-input class
jQuery('#' + f).on('change', 'input, textarea, select', function (e) {
if (e.originalEvent === undefined) return;
var el = jQuery(this);
el.addClass('changed-input');
var form = f in Epesi.confirmLeave.forms ? Epesi.confirmLeave.forms[f] : Epesi.confirmLeave.forms_freezed[f];
form[el.attr('name')] = true;
});
//take care if user refreshing or going to another page
jQuery(window).unbind('beforeunload').on('beforeunload', function() {
if (jQuery('.changed-input').length) {
return Epesi.confirmLeave.message;
}
});
},
deactivate: function(f) {
if (arguments.length) {
delete this.forms[f];
delete this.forms_freezed[f];
} else {
this.forms = {};
this.forms_freezed = {};
}

if (!Object.keys(this.forms).length) jQuery(window).unbind('beforeunload');
},
freeze: function(f) {
if (f in this.forms) {
this.forms_freezed[f] = this.forms[f];
delete this.forms[f];
}
}
},
updateIndicator: function() {
var s = jq('#' + Epesi.indicator);
if(s.length) {
if(Epesi.procOn) s.show();
else s.hide();
}
if (!Epesi.procOn) jq('#main_content').show();
},
updateIndicatorText: function(text) {
jq('#' + Epesi.indicator_text).html(text);
},
history_on:1,
history_add:function(id){
Epesi.history_on=-1;
unFocus.History.addHistory(id);
},
get_ie_version:function() {
var rv = -1; // Return value assumes failure.
if (navigator.appName == 'Microsoft Internet Explorer') {
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null)
rv = parseFloat(RegExp.$1);
}
return rv;
},
ie:false,
init:function(cl_id,path,params) {
var ie_ver = Epesi.get_ie_version();
if (ie_ver!=-1) {
if(ie_ver<8.0) {
alert("Sorry but your version of Internet Explorer browser is not supported.\nYou should upgrade it or install Mozilla Firefox.");
window.location = "http://www.mozilla.com/firefox/";
} else {
Epesi.ie = true;
}
}

Epesi.client_id=cl_id;
Epesi.process_file=path;

Epesi.history_add(0);
if(typeof params == 'undefined')
params = '';
Epesi.request(params,0);
unFocus.History.addEventListener('historyChange',function(history_id){
switch(Epesi.history_on){
case -1: Epesi.history_on=1;
return;
case 1: Epesi.request('',history_id);
}
});
},
request: function(url,history_id) {
Epesi.procOn++;
Epesi.updateIndicator();
var keep_focus_field = null;
jQuery.ajax(Epesi.process_file, {
method: 'post',
data: {
history: history_id,
url: url
},
complete: function(xhr,t) {
Epesi.procOn--;
Epesi.append_js('jQuery(document).trigger(\'e:load\');Epesi.updateIndicator();');
if(keep_focus_field!=null) {
Epesi.append_js('jQuery("#'+keep_focus_field+':visible").focus();');
}
},
success: function(t) {
if(typeof document.activeElement != "undefined") keep_focus_field = document.activeElement.getAttribute("id");
jQuery(document).trigger('e:loading');
},
error: function(t,type,error) {
//throw(type+": "+e);
alert(type+' ('+error+')');
Epesi.text(type+": "+error,'error_box','p');
}
});
},
href: function(url,indicator,mode,disableConfirmLeave) {
if (typeof disableConfirmLeave == 'undefined' && !Epesi.confirmLeave.check()) return;
if(Epesi.procOn==0 || mode=='allow'){
if(indicator=='') indicator=Epesi.default_indicator;
Epesi.updateIndicatorText(indicator);
Epesi.request(url);
} else if(mode=='queue')
setTimeout('Epesi.href("'+url+'", "'+indicator+'", "'+mode+'")',500);
},
submit_form: function(formName, modulePath, indicator) {
action = jQuery.param({'__action_module__': encodeURIComponent(modulePath)});
Epesi.confirmLeave.freeze(formName);
jQuery('form[name="' + formName + '"] input[name="submited"]').val(1);
_chj(jQuery('form[name="'+formName+'"]').serialize() +'&' + action, indicator, '');
jQuery('form[name="' + formName + '"] input[name="submited"]').val(0);
},
text: function(txt,idt,type) {
var t=jq('#'+idt);
if(!t.length) return;
if(type=='i')//instead
t.html(txt);
else if(type=='p')//prepend
t.prepend(txt);
else if(type=='a')//append
t.append(txt);
},
//js loader
loaded_jss:new Array(),
to_load_jss:new Array(),
to_append_jss:new Array(),
js_loader_running:false,
load_js:function(file) {
if (Epesi.loaded_jss.indexOf(file)!=-1) return;
Epesi.to_load_jss.push(file);
if(Epesi.js_loader_running==false) {
Epesi.js_loader_running=true;
Epesi.js_loader();
}
},
append_js:function(texti) {
if(Epesi.js_loader_running==false) {
Epesi.append_js_script(texti);
} else
Epesi.to_append_jss.push(texti);
},
append_js_script:function(texti) {
fileref=document.createElement("script");
fileref.setAttribute("type", "text/javascript");
fileref.text = texti;
document.getElementsByTagName("head").item(0).appendChild(fileref);
},
js_loader:function() {
file = Epesi.to_load_jss.shift();
if(typeof file != 'undefined') {
fileref=document.createElement("script")
fileref.setAttribute("type", "text/javascript");
fileref.setAttribute("src", file);
fileref.onload=fileref.onreadystatechange=function() {
if (fileref.readyState && fileref.readyState != 'loaded' && fileref.readyState != 'complete')
return;
Epesi.loaded_jss.push(file);
Epesi.js_loader();
}
document.getElementsByTagName("head").item(0).appendChild(fileref);
} else {
jq(Epesi.to_append_jss).each(function(i,texti) {
Epesi.append_js_script(texti);
});
Epesi.to_append_jss.length=0;
Epesi.js_loader_running = false;
}
},
//csses
loaded_csses:new Array(),
load_css:function(file) {
if (Epesi.loaded_csses.indexOf(file)!=-1) return false;
fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", file);
document.getElementsByTagName("head").item(0).appendChild(fileref);
Epesi.loaded_csses.push(file);
return true;
}
};
_chj=Epesi.href;
jQuery(document).ajaxSend(function(ev,xhr,settings){
xhr.setRequestHeader('X-Client-ID', Epesi.client_id);
});

function getTotalTopOffet(e) {
var ret=0;
while (e!=null) {
ret += e.offsetTop;
e = e.offsetParent;
}
return ret;
};
is_visible = function(element) {
if (!element) return false;
var display = jQuery(element).css('display');
if (display == "none") return false;
if (element.parentNode && element.parentNode.style) {
xxx = element.parentNode;
return is_visible(element.parentNode);
}
return true;
};
jq=jQuery;

+ 2
- 20
index.php View File

@@ -59,26 +59,8 @@ ob_start();
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="SKYPE_TOOLBAR" content="SKYPE_TOOLBAR_PARSER_COMPATIBLE" />
<meta name="robots" content="NOINDEX, NOARCHIVE">
<?php
ini_set('include_path', 'libs/minify' . PATH_SEPARATOR . '.' . PATH_SEPARATOR . 'libs' . PATH_SEPARATOR . ini_get('include_path'));
require_once('Minify/Build.php');
$jquery = DEBUG_JS ? 'vendor/bower-asset/gentelella/vendors/jquery/dist/jquery.js' : 'vendor/bower-asset/gentelella/vendors/jquery/dist/jquery.min.js';
$bootstrap = DEBUG_JS ? 'vendor/bower-asset/gentelella/vendors/bootstrap/dist/js/bootstrap.js' : 'vendor/bower-asset/gentelella/vendors/bootstrap/dist/js/bootstrap.min.js';
$select2 = DEBUG_JS ? 'vendor/bower-asset/gentelella/vendors/select2/dist/js/select2.js' : 'vendor/bower-asset/gentelella/vendors/select2/dist/js/select2.min.js';
$jquery_ui = DEBUG_JS ? 'libs/jquery-ui-1.12.1.custom.js':'libs/jquery-ui-1.12.1.custom.min.js';
$jses = array($jquery, $bootstrap, 'libs/jquery-ui-1.12.1.custom.min.js', 'libs/HistoryKeeper.js','include/epesi.js', 'libs/jquery.clonePosition.js', $select2,'libs/Chart.js');
if(!DEBUG_JS) {
$jsses_build = new Minify_Build($jses);
$jsses_src = $jsses_build->uri('serve.php?' . http_build_query(array('f' => array_values($jses))));
echo("<script type='text/javascript' src='$jsses_src'></script>");
} else {
foreach($jses as $js)
print("<script type='text/javascript' src='$js'></script>");
}
$csses = array('libs/jquery-ui-1.12.1.custom.min.css', 'vendor/bower-asset/gentelella/vendors/bootstrap/dist/css/bootstrap.css', 'vendor/bower-asset/gentelella/build/css/custom.css','vendor/bower-asset/gentelella/vendors/select2/dist/css/select2.css','vendor/bower-asset/gentelella/vendors/font-awesome/css/font-awesome.min.css');
foreach($csses as $css)
print('<link href="'.$css.'" rel="stylesheet" type="text/css">');
?>
<script type='text/javascript' src='dist/index.js'></script>
<link href='dist/styles.css' rel="stylesheet" type="text/css">
<style type="text/css">

#epesiStatus {


+ 0
- 12269
libs/Chart.js
File diff suppressed because it is too large
View File


+ 0
- 4
libs/HistoryKeeper.js View File

@@ -1,4 +0,0 @@
/* unFocus.History, version2.0 (beta 4) (2009/07/09)
Copyright: 2005-2009, Kevin Newman (http://www.unfocus.com/)
License: MIT - license.txt */
eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('4(!H.l)6 l={};l.x=2(){9.h={};t(6 i=0;i<I.m;i++){9.h[I[i]]=[]}};l.x.J={K:2(a,b){t(6 i=0;i<9.h[a].m;i++)4(9.h[a][i]==b)7;9.h[a].18(b)},19:2(a,b){t(6 i=0;i<9.h[a].m;i++){4(9.h[a][i]==b){9.h.1a(i,1);7}}},p:2(a,b){t(6 i=0;i<9.h[a].m;i++)9.h[a][i](b)}};l.L=(2(){2 y(){6 c=9,z=1b,u,3;6 d=2(){7 M.N.1c(1)};3=d();6 e=2(a){H.M.N=a};2 O(){6 a=d();4(3!=a){3=a;c.p("n",a)}}4(A)u=A(O,z);c.1d=2(){7 3};c.k=2 k(a){4(3!=a){3=a;e(a);c.p("n",a)}7 r};4(s.P)s.P=\'1e\';4(/Q\\/\\d+/.1f(B.R)&&B.R.S(/Q\\/(\\d+)/)[1]<1g){6 f=s.m,v={},o,w=T;2 U(){o=j.V("1h");o.W="1i";o.1j="1k";j.q.X(o,j.q.Y)}e=2(a){v[f]=a;o.1l="#"+d();o.1m()};d=2(){7 v[f]};v[f]=3;2 Z(a){4(3!=a){3=a;f=s.m+1;w=r;e(a);c.p("n",a);w=T}7 r}c.k=2(a){U();c.k=Z;7 c.k(a)};2 10(){4(!w){6 a=s.m;4(a!=f){f=a;6 b=d();4(3!=b){3=b;c.p("n",b)}}}};1n(u);u=A(10,z)}1o 4(/*@1p!@*/0&&B.1q.S(/1r (\\d+\\.\\d+)/)[1]>=5.5){4(j.11&&j.11>=8)7;6 g,C;2 12(){6 a="1s";g=j.V("1t");g.D("1u",a);g.D("W",a);g.D("1v",\'1w:;\');g.13.1x="1y";g.13.1z="-1A";j.q.X(g,j.q.Y);C=1B[a];E(3,r)}2 E(a){1C(C.j){1D("1E/F");1F("<F><14></14><q 1G",\'1H="1I.l.L.G(\\\'\'+a+\'\\\');">\',a+"</q></F>");1J()}}2 15(a){3=a;c.p("n",a)}c.G=2(){c.G=15};2 16(a){4(3!=a){3=a;E(a)}7 r};c.k=2(a){12();c.k=16;7 c.k(a)};c.K("n",2(a){e(a)})}}y.J=17 l.x("n");7 17 y()})();',62,108,'||function|_currentHash|if||var|return||this||||||||_listeners||document|addHistory|unFocus|length|historyChange|_form|notifyListeners|body|true|history|for|_intervalID|_historyStates|_recentlyAdded|EventManager|Keeper|_pollInterval|setInterval|navigator|_historyFrameRef|setAttribute|_createHistoryHTML|html|_updateFromHistory|window|arguments|prototype|addEventListener|History|location|hash|_watchHash|navigationMode|WebKit|appVersion|match|false|_createSafariSetHashForm|createElement|id|insertBefore|firstChild|addHistorySafari|_watchHistoryLength|documentMode|_createHistoryFrame|style|head|updateFromHistory|addHistoryIE|new|push|removeEventListener|splice|200|substring|getCurrent|compatible|test|420|form|unFocusHistoryForm|method|get|action|submit|clearInterval|else|cc_on|userAgent|MSIE|unFocusHistoryFrame|iframe|name|src|javascript|position|absolute|top|900px|frames|with|open|text|write|onl|oad|parent|close'.split('|'),0,{}))

+ 72
- 0
libs/HistoryKeeper/EventManager.js View File

@@ -0,0 +1,72 @@
/*
unFocus.EventManager, version 1.0 (svn $Revision: 32 $) $Date: 2009-06-13 03:32:05 -0400 (Sat, 13 Jun 2009) $
Copyright: 2005-2009, Kevin Newman (http://www.unfocus.com/)
http://www.opensource.org/licenses/mit-license.php
*/
// Package: unFocus.Utilities
// make sure faux-namespace is available before adding to it
if (!window.unFocus) var unFocus = {};

/** Class: EventManager
* Provides the interface and functionality to a Subscriber/Subscriber Pattern.
*
**/
/*
Constructor: EventManager
The Constructor (Prototype) function.

Parameters:
[type1 [, type2 [, etc.]]] - Optionally sets up an empty array for each named event.
*/
unFocus.EventManager = function() {
this._listeners = {};
for (var i = 0; i < arguments.length; i++) {
this._listeners[arguments[i]] = [];
}
};

unFocus.EventManager.prototype = {
/*
Method: addEventListener
Adds an event listener to the specified type.

Parameters:
$name - The event name.
$listener - The function to be called when the event fires.
*/
addEventListener: function($name, $listener) {
// check that listener is not in list
for (var i = 0; i < this._listeners[$name].length; i++)
if (this._listeners[$name][i] == $listener) return;
// add listener to appropriate list
this._listeners[$name].push($listener);
},
/*
Method: removeEventListener
Removes an event listener.
Parameters:
$name - The event name.
$listener - The function to be removed.
*/
removeEventListener: function($name, $listener) {
// search for the listener method
for (var i = 0; i < this._listeners[$name].length; i++) {
if (this._listeners[$name][i] == $listener) {
this._listeners.splice(i,1);
return;
}
}
},
/* Method: notifyListeners
Notifies the listeners of an event.
Parameters:
$name - The name of event to fire.
$data - The object to pass to the subscribed method (the Event Object).
*/
notifyListeners: function($name, $data) {
for (var i = 0; i < this._listeners[$name].length; i++)
this._listeners[$name][i]($data);
}
};

+ 272
- 0
libs/HistoryKeeper/History.js View File

@@ -0,0 +1,272 @@
/*
unFocus.History, version 2.0 (beta 1) (svn $Revision: 32 $) $Date: 2009-06-13 03:32:05 -0400 (Sat, 13 Jun 2009) $
Copyright: 2005-2009, Kevin Newman (http://www.unfocus.com/)
http://www.opensource.org/licenses/mit-license.php
*/

/*
Class: unFocus.History
A singleton with subscriber interface (<unFocus.EventManager>)
that keeps a history and provides deep links for Flash and AJAX apps
*/
unFocus.History = (function() {

function Keeper() {
var _this = this,
// set the poll interval here.
_pollInterval = 200, _intervalID,
_currentHash;

/*
method: _getHash
A private method that gets the Hash from the location.hash property.
returns:
a string containing the current hash from the url
*/
var _getHash = function() {
return location.hash.substring(1);
};
// get initial hash
_currentHash = _getHash();
/*
method: _setHash
A private method that sets the Hash on the location string (the current url).
*/
var _setHash = function($newHash) {
window.location.hash = $newHash;
};
/*
method: _watchHash
A private method that is called every n miliseconds (<_pollInterval>) to check if the hash has changed.
This is the primary Hash change detection method for most browsers. It doesn't work to detect the hash
change in IE 5.5+ or various other browsers. Workarounds like the iframe method are used for those
browsers (IE 5.0 will use an anchor creation hack).
*/
function _watchHash() {
var $newHash = _getHash();
if (_currentHash != $newHash) {
_currentHash = $newHash;
_this.notifyListeners("historyChange", $newHash);
}
}
// Put the hash check on a timer.
if (setInterval) _intervalID = setInterval(_watchHash, _pollInterval);
/*
method: getCurrentBookmark
A public method to retrieve the current history string.
returns:
The current History Hash
*/
_this.getCurrent = function() {
return _currentHash;
};
/*
method: addHistory
A public method to add a new history, and set the deep link. This method should be given a string.
It does no serialization.
returns:
Boolean - true if supported and set, false if not
*/
_this.addHistory = function addHistory($newHash) {
if (_currentHash != $newHash) {
_currentHash = $newHash;
_setHash($newHash);
_this.notifyListeners("historyChange",$newHash);
}
return true;
};

/**
* These are the platform specific override methods. Since some platforms (IE 5.5+, Safari)
* require almost completely different techniques to create history entries, browser detection is
* used and the appropriate method is created. The bugs these fixes address are very tied to the
* specific implementations of these browsers, and not necessarily the underlying html engines.
* Sometimes, bugs related to history management can be tied even to a specific skin in browsers
* like Opera.
*/
// opera
if (history.navigationMode)
history.navigationMode = 'compatible';
// Safari 2.04 and less (and WebKit less than 420 - these hacks are not needed by the most recent nightlies)
// :TODO: consider whether this aught to check for Safari or WebKit - is this a safar problem, or a does it
// happen in other WebKit based software? OmniWeb (WebKit 420+) seems to work, though there's a sync issue.
if (/WebKit\/\d+/.test(navigator.appVersion) && navigator.appVersion.match(/WebKit\/(\d+)/)[1] < 420) {
// this will hold the old history states, since they can't be reliably taken from the location object
var _unFocusHistoryLength = history.length,
_historyStates = {}, _form,
_recentlyAdded = false;
// Setting the hash directly in Safari seems to cause odd content refresh behavior.
// We'll use a form to submit to a #hash location instead. I'm assuming this works,
// since I saw it done this way in SwfAddress (gotta give credit where credit it due ;-) ).
function _createSafariSetHashForm() {
_form = document.createElement("form");
_form.id = "unFocusHistoryForm";
_form.method = "get";
document.body.insertBefore(_form,document.body.firstChild);
}
// override the old _setHash method to use the new form
_setHash = function($newHash) {
_historyStates[_unFocusHistoryLength] = $newHash;
_form.action = "#" + _getHash();
_form.submit();
};
// override the old _getHash method, since Safari doesn't update location.hash (fixed in nightlies)
_getHash = function() {
return _historyStates[_unFocusHistoryLength];
};
// set initial history entry
_historyStates[_unFocusHistoryLength] = _currentHash;
function addHistorySafari($newHash) {
if (_currentHash != $newHash) {
_currentHash = $newHash;
_unFocusHistoryLength = history.length+1;
_recentlyAdded = true;
_setHash($newHash);
_this.notifyListeners("historyChange",$newHash);
_recentlyAdded = false;
}
return true;
}
// provide alternative addHistory
_this.addHistory = function($newHash) { // adds history and bookmark hash
// setup the form fix
_createSafariSetHashForm();
// replace with slimmer version...
// :TODO: rethink this - it's adding an extra scope to the chain, which might
// actually cost more at runtime than a simple if statement. Can this be done
// without adding to the scope chain? The replaced scope holds no values. Does
// it keep it's place in the scope chain?
_this.addHistory = addHistorySafari;
// ...do first call
return _this.addHistory($newHash);
};
function _watchHistoryLength() {
if (!_recentlyAdded) {
var _historyLength = history.length;
if (_historyLength != _unFocusHistoryLength) {
_unFocusHistoryLength = _historyLength;
var $newHash = _getHash();
if (_currentHash != $newHash) {
_currentHash = $newHash;
_this.notifyListeners("historyChange", $newHash);
}
}
}
};
// since it doesn't work, might as well cancel the location.hash check
clearInterval(_intervalID);
// watch the history.length prop for changes instead
_intervalID = setInterval(_watchHistoryLength, _pollInterval);
// IE 5.5+ Windows
} else if (/*@cc_on!@*/0 && navigator.userAgent.match(/MSIE (\d+\.\d+)/)[1] >= 5.5) {
// :HACK: Quick and dirty IE8 support (makes IE8 use standard timer method).
if (document.documentMode && document.documentMode >= 8)
return;
/* iframe references */
var _historyFrameObj, _historyFrameRef;
/*
method: _createHistoryFrame
This is for IE only for now.
*/
function _createHistoryFrame() {
var $historyFrameName = "unFocusHistoryFrame";
_historyFrameObj = document.createElement("iframe");
_historyFrameObj.setAttribute("name", $historyFrameName);
_historyFrameObj.setAttribute("id", $historyFrameName);
// :NOTE: _Very_ experimental
_historyFrameObj.setAttribute("src", 'javascript:;');
_historyFrameObj.style.position = "absolute";
_historyFrameObj.style.top = "-900px";
document.body.insertBefore(_historyFrameObj,document.body.firstChild);
// get reference to the frame from frames array (needed for document.open)
// :NOTE: there might be an issue with this according to quirksmode.org
// http://www.quirksmode.org/js/iframe.html
_historyFrameRef = frames[$historyFrameName];
// add base history entry
_createHistoryHTML(_currentHash, true);
}
/*
method: _createHistoryHTML
This is an alternative to <_setHistoryHTML> that is used by IE (and others if I can get it to work).
This method will create the history page completely in memory, with no need to download a new file
from the server.
*/
function _createHistoryHTML($newHash) {
with (_historyFrameRef.document) {
open("text/html");
write("<html><head></head><body onl",
'oad="parent.unFocus.History._updateFromHistory(\''+$newHash+'\');">',
$newHash+"</body></html>");
close();
}
}
/*
method: _updateFromHistory
A private method that is meant to be called only from HistoryFrame.html.
It is not meant to be used by an end user even though it is accessable as public.
*/
// hides the first call to the method, and sets up the real method for the rest of the calls
function updateFromHistory($hash) {
_currentHash = $hash;
_this.notifyListeners("historyChange", $hash);
}
_this._updateFromHistory = function() {
_this._updateFromHistory = updateFromHistory;
};

function addHistoryIE($newHash) { // adds history and bookmark hash
if (_currentHash != $newHash) {
// :NOTE: IE will create an entry if there is an achor on the page, but it
// does not allow you to detect the state change.
_currentHash = $newHash;
// sets hash and notifies listeners
_createHistoryHTML($newHash);
}
return true;
};
_this.addHistory = function($newHash) {
// do initialization stuff on first call
_createHistoryFrame();
// replace this function with a slimmer one on first call
_this.addHistory = addHistoryIE;
// call the first call
return _this.addHistory($newHash);
};
// anonymous method - subscribe to self to update the hash when the history is updated
_this.addEventListener("historyChange", function($hash) { _setHash($hash) });
}
}
Keeper.prototype = new unFocus.EventManager("historyChange");

return new Keeper();

})();

+ 0
- 7
libs/jquery-ui-1.12.1.custom.min.css
File diff suppressed because it is too large
View File


+ 0
- 9
libs/jquery-ui-1.12.1.custom.min.js
File diff suppressed because it is too large
View File


+ 0
- 6
libs/jquery-ui.txt View File

@@ -1,6 +0,0 @@
custom package:
- all core
- all interactions
- widgets - only: accordion, autocomplete, menu, mouse

Tooltip from jquery.ui conflicts with tooltip from bootstrap!

+ 52
- 0
package.json View File

@@ -0,0 +1,52 @@
{
"name": "epesi",
"version": "1.0.0",
"description": "![Epesi Logo](/images/logo.png)\r =\r [![SourceForge](https://img.shields.io/sourceforge/dt/epesi.svg)](https://sourceforge.net/projects/epesi)",
"main": "index.js",
"directories": {
"doc": "docs",
"test": "tests"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Telaxus/EPESI.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/Telaxus/EPESI/issues"
},
"homepage": "https://github.com/Telaxus/EPESI#readme",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.6.0",
"css-loader": "^0.28.7",
"expose-loader": "^0.7.3",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^0.11.2",
"less": "^2.7.2",
"less-loader": "^4.0.5",
"resolve-url-loader": "^2.1.0",
"script-loader": "^0.7.1",
"style-loader": "^0.18.2",
"url-loader": "^0.5.9",
"webpack": "^3.6.0"
},
"dependencies": {
"babel-runtime": "^6.26.0",
"bluebird": "^3.5.0",
"bootstrap": "^3.3.7",
"chart.js": "^2.7.0",
"font-awesome": "^4.7.0",
"gentelella": "^1.3.0",
"jquery": "^2.x.x",
"jquery-ui": "^1.12.1",
"select2": "^4.0.3"
}
}

+ 233
- 0
src/epesi.js View File

@@ -0,0 +1,233 @@
/*
* @author Paul Bukowski <pbukowski@telaxus.com>
* @version 1.0
* @copyright Copyright &copy; 2007, Telaxus LLC
* @licence MIT
*/

import Loader from './loader';

const Epesi = {
loader: new Loader(),
default_indicator:'loading...',
procOn:0,
client_id:0,
process_file:'process.php',
indicator:'epesiStatus',
indicator_text:'epesiStatusText',
confirmLeave: {
// object of form ids which require confirmation for leaving the page
// store changed fields to pass through submit state
forms:{},
// store currently submitted form. If it'll fail to validate then we
// have list of changed fields
forms_freezed:{},
message:'Leave page?',
//checks if leaving the page is approved
check: function() {
//remove non-existent forms from the array
jQuery.each(this.forms, function(f) {
if (!jQuery('#'+f).length) Epesi.confirmLeave.deactivate(f);
});
jQuery.each(this.forms_freezed, function(f) {
if (!jQuery('#'+f).length) Epesi.confirmLeave.deactivate(f);
});
//check if there is any not freezed form with changed values to confirm leave
var requires_confirmation = false;
if (Object.keys(this.forms).length) {
for (var form in this.forms) {
if (jQuery('#' + form + ' .changed-input').length) {
requires_confirmation = true;
break;
}
}
}
if (requires_confirmation) {
//take care if user disabled alert messages
var openTime = new Date();
try {
var confirmed = confirm(this.message);
} catch(e) {
var confirmed = true;
}
var closeTime = new Date();
if ((closeTime - openTime) > 350 && !confirmed) return false;
this.deactivate();
}
return true;
},
activate: function(f, m) {
this.message = m;
// add form or restore from freezed state - form is freezed for submit
if (!(f in this.forms)) {
if (f in this.forms_freezed) {
this.forms[f] = this.forms_freezed[f];
delete this.forms_freezed[f];
} else {
this.forms[f] = {};
}
}
// apply class to all changed inputs - required for validation failure
for (var key in this.forms[f]) {
jQuery('#' + f + ' [name="' + key + '"]').addClass('changed-input');
}
// on change add changed-input class
jQuery('#' + f).on('change', 'input, textarea, select', function (e) {
if (e.originalEvent === undefined) return;
var el = jQuery(this);
el.addClass('changed-input');
var form = f in Epesi.confirmLeave.forms ? Epesi.confirmLeave.forms[f] : Epesi.confirmLeave.forms_freezed[f];
form[el.attr('name')] = true;
});
//take care if user refreshing or going to another page
jQuery(window).unbind('beforeunload').on('beforeunload', function() {
if (jQuery('.changed-input').length) {
return Epesi.confirmLeave.message;
}
});
},
deactivate: function(f) {
if (arguments.length) {
delete this.forms[f];
delete this.forms_freezed[f];
} else {
this.forms = {};
this.forms_freezed = {};
}

if (!Object.keys(this.forms).length) jQuery(window).unbind('beforeunload');
},
freeze: function(f) {
if (f in this.forms) {
this.forms_freezed[f] = this.forms[f];
delete this.forms[f];
}
}
},
updateIndicator: function() {
var s = jq('#' + Epesi.indicator);
if(s.length) {
if(Epesi.procOn) s.show();
else s.hide();
}
if (!Epesi.procOn) jq('#main_content').show();
},
updateIndicatorText: function(text) {
jq('#' + Epesi.indicator_text).html(text);
},
history_on:1,
history_add:function(id){
Epesi.history_on=-1;
unFocus.History.addHistory(id);
},
get_ie_version:function() {
var rv = -1; // Return value assumes failure.
if (navigator.appName == 'Microsoft Internet Explorer') {
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null)
rv = parseFloat(RegExp.$1);
}
return rv;
},
ie:false,
init:function(cl_id,path,params) {
var ie_ver = Epesi.get_ie_version();
if (ie_ver!=-1) {
if(ie_ver<8.0) {
alert("Sorry but your version of Internet Explorer browser is not supported.\nYou should upgrade it or install Mozilla Firefox.");
window.location = "http://www.mozilla.com/firefox/";
} else {
Epesi.ie = true;
}
}

Epesi.client_id=cl_id;
Epesi.process_file=path;

Epesi.history_add(0);
if(typeof params == 'undefined')
params = '';
Epesi.request(params,0);
unFocus.History.addEventListener('historyChange',function(history_id){
switch(Epesi.history_on){
case -1: Epesi.history_on=1;
return;
case 1: Epesi.request('',history_id);
}
});
},
request: function(url,history_id) {
Epesi.procOn++;
Epesi.updateIndicator();
var keep_focus_field = null;
jQuery.ajax(Epesi.process_file, {
method: 'post',
data: {
history: history_id,
url: url
},
complete: function(xhr,t) {
Epesi.procOn--;
Epesi.append_js('jQuery(document).trigger(\'e:load\');Epesi.updateIndicator();');
if(keep_focus_field!=null) {
Epesi.append_js('jQuery("#'+keep_focus_field+':visible").focus();');
}
},
success: function(t) {
if(typeof document.activeElement != "undefined") keep_focus_field = document.activeElement.getAttribute("id");
jQuery(document).trigger('e:loading');
},
error: function(t,type,error) {
//throw(type+": "+e);
alert(type+' ('+error+')');
Epesi.text(type+": "+error,'error_box','p');
}
});
},
href: function(url,indicator,mode,disableConfirmLeave) {
if (typeof disableConfirmLeave == 'undefined' && !Epesi.confirmLeave.check()) return;
if(Epesi.procOn==0 || mode=='allow'){
if(indicator=='') indicator=Epesi.default_indicator;
Epesi.updateIndicatorText(indicator);
Epesi.request(url);
} else if(mode=='queue')
setTimeout('Epesi.href("'+url+'", "'+indicator+'", "'+mode+'")',500);
},
submit_form: function(formName, modulePath, indicator) {
action = jQuery.param({'__action_module__': encodeURIComponent(modulePath)});
Epesi.confirmLeave.freeze(formName);
jQuery('form[name="' + formName + '"] input[name="submited"]').val(1);
_chj(jQuery('form[name="'+formName+'"]').serialize() +'&' + action, indicator, '');
jQuery('form[name="' + formName + '"] input[name="submited"]').val(0);
},
text: function(txt,idt,type) {
var t=jq('#'+idt);
if(!t.length) return;
if(type=='i')//instead
t.html(txt);
else if(type=='p')//prepend
t.prepend(txt);
else if(type=='a')//append
t.append(txt);
},
load_js:function(file) {
Epesi.loader.load_js(file);
},
append_js:function(texti) {
Epesi.loader.execute_js(texti);
},
append_js_script:function(texti) {
console.warn('DEPRECATED: use Loader.execute_js instead');
Loader.insertScript(texti);
},
js_loader:function() {
console.warn('DEPRECATED: load is invoked implicitly');
Epesi.loader.load();
},
load_css:function(file) {
Epesi.loader.load_css(file);
}
};

export default Epesi;

+ 67
- 0
src/index.js View File

@@ -0,0 +1,67 @@
import jQuery from 'expose-loader?jq!expose-loader?jQuery!expose-loader?$!jquery';

import 'bootstrap';
import 'bootstrap/less/bootstrap.less';

import 'jquery-ui';
import 'jquery-ui/ui/widgets/sortable';
import 'jquery-ui/themes/base/all.css'

import 'select2';
import 'select2/dist/css/select2.css';

import 'script-loader!../libs/HistoryKeeper/EventManager.js';
import 'script-loader!../libs/HistoryKeeper/History.js';

import 'script-loader!../libs/jquery.clonePosition.js';
import Chart from 'chart.js';

import 'gentelella/production/less/custom.css';
import 'font-awesome/css/font-awesome.css';

window.Chart = Chart;

import Epesi from './epesi';

window.focus_by_id = (idd) => {
let xx = document.getElementById(idd);
if (xx) setTimeout(function () {
jq(xx).focus();
}, 200);
};

window.addslashes = x => x.replace(/('|"|\\)/g, "\\$1")

window.wait_while_null = (id, action) => {
if (eval('typeof(' + id + ')') != 'undefined')
eval(action);
else
setTimeout('wait_while_null(\'' + addslashes(id) + '\', \'' + addslashes(action) + '\')', 200);
};

window._chj = Epesi.href;

jQuery(document).ajaxSend(function (ev, xhr, settings) {
xhr.setRequestHeader('X-Client-ID', Epesi.client_id);
});

window.getTotalTopOffet = e => {
let ret = 0;
while (e != null) {
ret += e.offsetTop;
e = e.offsetParent;
}
return ret;
};
window.is_visible = function (element) {
if (!element) return false;
let display = jQuery(element).css('display');
if (display == "none") return false;
if (element.parentNode && element.parentNode.style) {
xxx = element.parentNode;
return is_visible(element.parentNode);
}
return true;
};

window.Epesi = Epesi;

+ 105
- 0
src/loader.js View File

@@ -0,0 +1,105 @@
import Promise from 'bluebird';

class Loader {
loading = false;
loaded_js = [];
to_load_js = [];
to_execute_js = [];
to_load_css = [];
loaded_css = [];

static loadScript = file => {
return new Promise(function (resolve, reject) {
let script = document.createElement('script');
script.type = 'text/javascript';
script.onerror = reject;
script.src = file;
script.onload = script.onreadystatechange = function (_, isAbort) {
if (isAbort || !script.readyState || /loaded|complete/.test(script.readyState)) {
script.onload = script.onreadystatechange = null;
script = undefined;

if (!isAbort) {
resolve();
}
}
};
document.getElementsByTagName('head').item(0).appendChild(script);
});
};

static loadCss = file => {
return new Promise(function (resolve, reject) {
let link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.onerror = reject;
link.href = file;
link.onload = link.onreadystatechange = function (_, isAbort) {
if (isAbort || !link.readyState || /loaded|complete/.test(link.readyState)) {
link.onload = link.onreadystatechange = null;
link = undefined;

if (!isAbort) {
resolve();
}
}
};
document.getElementsByTagName('head').item(0).appendChild(link);
});
};

static insertScript = code => {
return new Promise(function (resolve, reject) {
let script = document.createElement('script');
script.type = 'text/javascript';
script.onerror = reject;
script.text = code;
document.getElementsByTagName('head').item(0).appendChild(script);
});
};

load_js = async file => {
if (this.loaded_js.includes(file) || this.to_load_js.includes(file)) return;
this.to_load_js.push(file);
await this.load();
};

load_css = async file => {
if (this.loaded_css.includes(file) || this.to_load_css.includes(file)) return;
this.to_load_css.push(file);
await this.load();
};

execute_js = async code => {
this.to_execute_js.push(code);
await this.load();
};

load = async () => {
if(this.loading === true) return;
this.loading = true;

let file;
while(file = this.to_load_js.shift()) {
if(this.loaded_js.includes(file)) continue;
await Loader.loadScript(file);
this.loaded_js.push(file);
}

let code;
while (code = this.to_execute_js.shift()) {
Loader.insertScript(code);
}

let css;
while (css = this.to_load_css.shift()) {
Loader.loadCss(css);
this.loaded_css.push(css);
}

this.loading = false;
}
}

export default Loader;

+ 45
- 0
webpack.config.js View File

@@ -0,0 +1,45 @@
const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
context: __dirname + "/src",
entry: "./index",
devtool: 'source-map',
output: {
path: __dirname + "/dist",
filename: "index.js"
},
module: {
loaders: [
{test: /bootstrap\/js\//, loader: 'imports?jQuery=jquery' },
{test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ["css-loader", "less-loader"]
})},
{test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})},
{test: /\.woff(2)?(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
{test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=10000&mimetype=application/octet-stream" },
{test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader" },
{test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=10000&mimetype=image/svg+xml" },
{test: /\.(png|jpg|gif)$/, loader: "file-loader" },
{
test: /\.js$/,
exclude: /(node_modules|bower_components|libs)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env'],
plugins: ["transform-class-properties"]
}
}
}
]
},
plugins: [
new ExtractTextPlugin("styles.css")
]
};

Loading…
Cancel
Save