Skip to content

Commit 67546f5

Browse files
committed
Merge branch 'master' of github.com:gskinner/regexr
2 parents 6578f5a + c4c3ce5 commit 67546f5

File tree

9 files changed

+2261
-13
lines changed

9 files changed

+2261
-13
lines changed

index.html

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@
3535
<script src="js/third-party/classList.js"></script>
3636
<script src="js/third-party/store.js"></script>
3737
<script src="js/third-party/placeholders.min.js"></script>
38-
<script src="js/Tracking.js"></script>
39-
<script src="js/BrowserHistory.js"></script>
38+
<script src="js/third-party/history.adapter.native.js"></script>
39+
<script src="js/third-party/history.js"></script>
4040
<script src="js/events/Event.js"></script>
4141
<script src="js/events/EventDispatcher.js"></script>
42-
<script src="js/events/DataEvent.js"></script>
4342
<script src="js/utils/Utils.js"></script>
43+
<script src="js/Tracking.js"></script>
44+
<script src="js/BrowserHistory.js"></script>
45+
<script src="js/events/DataEvent.js"></script>
4446
<script src="js/events/TransitionEvents.js"></script>
4547
<script src="js/Settings.js"></script>
4648
<script src="js/controls/Rating.js"></script>

js/BrowserHistory.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,51 @@ SOFTWARE.
2424
(function () {
2525
var s = {};
2626

27+
createjs.EventDispatcher.initialize(s);
2728
// public properties:
2829

2930
// private properties:
3031
s._currentPath = null;
32+
s._currentLocation = null;
3133

3234
// public methods:
3335
s.go = function (url) {
3436
if (s._currentPath === url) { return; }
3537
s._currentPath = url;
3638

3739
if (window.history.pushState) {
38-
window.history.pushState(null, null, url || "/");
40+
History.pushState(null, null, url || "/");
3941
} else {
4042
window.location.hash = url || "";
4143
}
44+
45+
s._currentLocation = document.location.toString();
46+
};
47+
48+
s.init = function() {
49+
History.init();
50+
51+
// Use history.js for modern browsers
52+
if (window.history.pushState) {
53+
History.Adapter.bind(window, 'statechange', $.bind(s, s.handleHistoryChange));
54+
} else {
55+
// Custom support for #tags (for ie9)
56+
window.addEventListener("hashchange", $.bind(s, s.handleHashChange));
57+
}
58+
};
59+
60+
s.handleHistoryChange = function(evt) {
61+
s.dispatchEvent("change");
62+
};
63+
64+
s.handleHashChange = function(evt) {
65+
var path = document.location.hash.substr(1);
66+
if (s._currentPath === path) {
67+
return;
68+
}
69+
s._currentPath = path;
70+
71+
s.dispatchEvent("change");
4272
};
4373

4474
// private methods:

js/controls/List.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,15 @@ SOFTWARE.
206206
return this.data[idx];
207207
};
208208

209+
p.findIndexByValue = function(key, value) {
210+
for (var i=0;i<this.data.length;i++) {
211+
if (this.data[i][key] == value) {
212+
return i;
213+
}
214+
}
215+
return -1;
216+
};
217+
209218
p.handleEvent = function(evt) {
210219
this.triggerChange(evt.currentTarget.index);
211220
};

js/index.template.js

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,18 @@ SOFTWARE.
3333
};
3434
var p = s.prototype = {};
3535
p._ctaAnimation = null;
36+
p.docView = null;
3637

3738
p.init = function () {
38-
39+
3940
// If the browser is not supported, don't let them in.
4041
if (!$.isSupported()) {
4142
return;
4243
}
4344

45+
BrowserHistory.init();
46+
BrowserHistory.on("change", this.handleHistoryChange, this);
47+
4448
if (document.location.host != "regexr.com" && document.location.host != "www.regexr.com") {
4549
$.removeClass($.el(".beta-banner"), "hidden");
4650
}
@@ -58,11 +62,12 @@ SOFTWARE.
5862
List.spinner = $.el(".spinner");
5963

6064
var docView = new DocView($.el("#docview"));
65+
this.docView = docView;
6166
var def = $.el("#docview .default");
6267
DocView.DEFAULT_TEXT = (def.textContent || def.innerText).trim().replace("{{ctrl}}", Utils.getCtrlKey().toLowerCase());
6368
docView.setText(); // need to do this as well as the defer below, to keep the history clean.
6469
$.defer(docView, docView.setText); // this fixes an issue with CodeMirror returning bad char positions at specific widths.
65-
70+
6671
def.style.display = "none";
6772

6873
docView.setExpression(DocView.DEFAULT_EXPRESSION).setSubstitution(DocView.DEFAULT_SUBSTITUTION);
@@ -112,7 +117,14 @@ SOFTWARE.
112117

113118
Settings.trackVisit();
114119
Settings.cleanSaveTokens();
120+
this.navigate();
121+
};
115122

123+
p.handleHistoryChange = function(evt) {
124+
this.navigate();
125+
};
126+
127+
p.navigate = function() {
116128
// Check for a deep-link
117129
var url = document.location.toString();
118130
var match = /[\/#\?]([\w\d]+)$/ig.exec(url);
@@ -121,11 +133,14 @@ SOFTWARE.
121133
id = match[1];
122134
}
123135

136+
if (ExpressionModel.id == $.idToNumber(id)+'') { return; }
137+
124138
if ($.isIDValid(id)) {
139+
var _this = this;
125140
ServerModel.getPatternByID(id).then(function (data) {
126141
ExpressionModel.setLastSave(data);
127142
var pattern = $.parsePattern(data.pattern);
128-
docView.populateAll(pattern.ex, pattern.flags, data.content, data.replace);
143+
_this.docView.populateAll(pattern.ex, pattern.flags, data.content, data.replace);
129144
}, function () {
130145
BrowserHistory.go();
131146
});

js/net/ExpressionModel.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ SOFTWARE.
2525
"use strict";
2626

2727
var s = {};
28+
createjs.EventDispatcher.initialize(s);
29+
2830
s.docView = null;
2931
s.id = null;
3032
s._lastSave = null;
@@ -76,6 +78,7 @@ SOFTWARE.
7678

7779
s.id = id;
7880
s._lastSave = pattern;
81+
s.dispatchEvent("change");
7982

8083
return result;
8184
};
@@ -85,10 +88,13 @@ SOFTWARE.
8588
};
8689

8790
s.setLastSave = function(value) {
91+
if (s.id == value.id) { return; }
92+
8893
s.id = value.id;
8994
if (Settings.getUpdateToken(s.id)) {
9095
s._lastSave = value;
9196
}
97+
s.dispatchEvent("change");
9298
};
9399

94100
s.getLastSave = function() {
@@ -98,6 +104,13 @@ SOFTWARE.
98104
return s._lastSave;
99105
};
100106

107+
s.setID = function(value) {
108+
if (s.id == value) { return; }
109+
110+
s.id = value;
111+
s.dispatchEvent("change");
112+
}
113+
101114
scope.ExpressionModel = s;
102115

103116
}(window));
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/**
2+
* History.js Native Adapter
3+
* @author Benjamin Arthur Lupton <[email protected]>
4+
* @copyright 2010-2011 Benjamin Arthur Lupton <[email protected]>
5+
* @license New BSD License <http://creativecommons.org/licenses/BSD/>
6+
*/
7+
8+
// Closure
9+
(function(window,undefined){
10+
"use strict";
11+
12+
// Localise Globals
13+
var History = window.History = window.History||{};
14+
15+
// Check Existence
16+
if ( typeof History.Adapter !== 'undefined' ) {
17+
throw new Error('History.js Adapter has already been loaded...');
18+
}
19+
20+
// Add the Adapter
21+
History.Adapter = {
22+
/**
23+
* History.Adapter.handlers[uid][eventName] = Array
24+
*/
25+
handlers: {},
26+
27+
/**
28+
* History.Adapter._uid
29+
* The current element unique identifier
30+
*/
31+
_uid: 1,
32+
33+
/**
34+
* History.Adapter.uid(element)
35+
* @param {Element} element
36+
* @return {String} uid
37+
*/
38+
uid: function(element){
39+
return element._uid || (element._uid = History.Adapter._uid++);
40+
},
41+
42+
/**
43+
* History.Adapter.bind(el,event,callback)
44+
* @param {Element} element
45+
* @param {String} eventName - custom and standard events
46+
* @param {Function} callback
47+
* @return
48+
*/
49+
bind: function(element,eventName,callback){
50+
// Prepare
51+
var uid = History.Adapter.uid(element);
52+
53+
// Apply Listener
54+
History.Adapter.handlers[uid] = History.Adapter.handlers[uid] || {};
55+
History.Adapter.handlers[uid][eventName] = History.Adapter.handlers[uid][eventName] || [];
56+
History.Adapter.handlers[uid][eventName].push(callback);
57+
58+
// Bind Global Listener
59+
element['on'+eventName] = (function(element,eventName){
60+
return function(event){
61+
History.Adapter.trigger(element,eventName,event);
62+
};
63+
})(element,eventName);
64+
},
65+
66+
/**
67+
* History.Adapter.trigger(el,event)
68+
* @param {Element} element
69+
* @param {String} eventName - custom and standard events
70+
* @param {Object} event - a object of event data
71+
* @return
72+
*/
73+
trigger: function(element,eventName,event){
74+
// Prepare
75+
event = event || {};
76+
var uid = History.Adapter.uid(element),
77+
i,n;
78+
79+
// Apply Listener
80+
History.Adapter.handlers[uid] = History.Adapter.handlers[uid] || {};
81+
History.Adapter.handlers[uid][eventName] = History.Adapter.handlers[uid][eventName] || [];
82+
83+
// Fire Listeners
84+
for ( i=0,n=History.Adapter.handlers[uid][eventName].length; i<n; ++i ) {
85+
History.Adapter.handlers[uid][eventName][i].apply(this,[event]);
86+
}
87+
},
88+
89+
/**
90+
* History.Adapter.extractEventData(key,event,extra)
91+
* @param {String} key - key for the event data to extract
92+
* @param {String} event - custom and standard events
93+
* @return {mixed}
94+
*/
95+
extractEventData: function(key,event){
96+
var result = (event && event[key]) || undefined;
97+
return result;
98+
},
99+
100+
/**
101+
* History.Adapter.onDomLoad(callback)
102+
* @param {Function} callback
103+
* @return
104+
*/
105+
onDomLoad: function(callback) {
106+
var timeout = window.setTimeout(function(){
107+
callback();
108+
},2000);
109+
window.onload = function(){
110+
clearTimeout(timeout);
111+
callback();
112+
};
113+
}
114+
};
115+
116+
// Try to Initialise History
117+
if ( typeof History.init !== 'undefined' ) {
118+
History.init();
119+
}
120+
121+
})(window);

0 commit comments

Comments
 (0)