This repository was archived by the owner on Apr 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 27.4k
/
Copy pathmessageFormatSelector.js
121 lines (105 loc) · 3.98 KB
/
messageFormatSelector.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
'use strict';
// NOTE: ADVANCED_OPTIMIZATIONS mode.
//
// This file is compiled with Closure compiler's ADVANCED_OPTIMIZATIONS flag! Be wary of using
// constructs incompatible with that mode.
/* global $interpolateMinErr: false */
/* global isFunction: false */
/* global noop: false */
/**
* @constructor
* @private
*/
function MessageSelectorBase(expressionFn, choices) {
var self = this;
this.expressionFn = expressionFn;
this.choices = choices;
if (choices['other'] === undefined) {
throw $interpolateMinErr('reqother', '“other” is a required option.');
}
this.parsedFn = function(context) { return self.getResult(context); };
this.parsedFn['$$watchDelegate'] = function $$watchDelegate(scope, listener, objectEquality) {
return self.watchDelegate(scope, listener, objectEquality);
};
this.parsedFn['exp'] = expressionFn['exp'];
this.parsedFn['expressions'] = expressionFn['expressions'];
}
MessageSelectorBase.prototype.getMessageFn = function getMessageFn(value) {
return this.choices[this.categorizeValue(value)];
};
MessageSelectorBase.prototype.getResult = function getResult(context) {
return this.getMessageFn(this.expressionFn(context))(context);
};
MessageSelectorBase.prototype.watchDelegate = function watchDelegate(scope, listener, objectEquality) {
var watchers = new MessageSelectorWatchers(this, scope, listener, objectEquality);
return function() { watchers.cancelWatch(); };
};
/**
* @constructor
* @private
*/
function MessageSelectorWatchers(msgSelector, scope, listener, objectEquality) {
var self = this;
this.scope = scope;
this.msgSelector = msgSelector;
this.listener = listener;
this.objectEquality = objectEquality;
this.lastMessage = undefined;
this.messageFnWatcher = noop;
var expressionFnListener = function(newValue, oldValue) { return self.expressionFnListener(newValue, oldValue); };
this.expressionFnWatcher = scope['$watch'](msgSelector.expressionFn, expressionFnListener, objectEquality);
}
MessageSelectorWatchers.prototype.expressionFnListener = function expressionFnListener(newValue, oldValue) {
var self = this;
this.messageFnWatcher();
var messageFnListener = function(newMessage, oldMessage) { return self.messageFnListener(newMessage, oldMessage); };
var messageFn = this.msgSelector.getMessageFn(newValue);
this.messageFnWatcher = this.scope['$watch'](messageFn, messageFnListener, this.objectEquality);
};
MessageSelectorWatchers.prototype.messageFnListener = function messageFnListener(newMessage, oldMessage) {
if (isFunction(this.listener)) {
this.listener.call(null, newMessage, newMessage === oldMessage ? newMessage : this.lastMessage, this.scope);
}
this.lastMessage = newMessage;
};
MessageSelectorWatchers.prototype.cancelWatch = function cancelWatch() {
this.expressionFnWatcher();
this.messageFnWatcher();
};
/**
* @constructor
* @extends MessageSelectorBase
* @private
*/
function SelectMessage(expressionFn, choices) {
MessageSelectorBase.call(this, expressionFn, choices);
}
function SelectMessageProto() {}
SelectMessageProto.prototype = MessageSelectorBase.prototype;
SelectMessage.prototype = new SelectMessageProto();
SelectMessage.prototype.categorizeValue = function categorizeSelectValue(value) {
return (this.choices[value] !== undefined) ? value : 'other';
};
/**
* @constructor
* @extends MessageSelectorBase
* @private
*/
function PluralMessage(expressionFn, choices, offset, pluralCat) {
MessageSelectorBase.call(this, expressionFn, choices);
this.offset = offset;
this.pluralCat = pluralCat;
}
function PluralMessageProto() {}
PluralMessageProto.prototype = MessageSelectorBase.prototype;
PluralMessage.prototype = new PluralMessageProto();
PluralMessage.prototype.categorizeValue = function categorizePluralValue(value) {
if (isNaN(value)) {
return 'other';
} else if (this.choices[value] !== undefined) {
return value;
} else {
var category = this.pluralCat(value - this.offset);
return (this.choices[category] !== undefined) ? category : 'other';
}
};