@twilio/conversations 1.3.0-rc8 → 2.0.0-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +210 -0
- package/README.md +22 -17
- package/dist/browser.js +7873 -0
- package/dist/browser.js.map +1 -0
- package/dist/docs/assets/css/main.css +2660 -0
- package/dist/docs/assets/images/icons.png +0 -0
- package/dist/docs/assets/images/icons@2x.png +0 -0
- package/dist/docs/assets/images/widgets.png +0 -0
- package/dist/docs/assets/images/widgets@2x.png +0 -0
- package/dist/docs/assets/js/main.js +248 -0
- package/dist/docs/assets/js/search.js +1 -0
- package/dist/docs/classes/AggregatedDeliveryReceipt.html +3286 -0
- package/dist/docs/classes/Client.html +4181 -0
- package/dist/docs/classes/Conversation.html +4397 -0
- package/dist/docs/classes/DetailedDeliveryReceipt.html +3265 -0
- package/dist/docs/classes/Media.html +3295 -0
- package/dist/docs/classes/Message.html +3713 -0
- package/dist/docs/classes/MessageBuilder.html +3280 -0
- package/dist/docs/classes/Participant.html +3517 -0
- package/dist/docs/classes/PushNotification.html +3232 -0
- package/dist/docs/classes/RestPaginator.html +3262 -0
- package/dist/docs/classes/UnsentMessage.html +3144 -0
- package/dist/docs/classes/User.html +3451 -0
- package/dist/docs/index.html +3394 -212
- package/dist/docs/interfaces/ClientOptions.html +3136 -0
- package/dist/docs/interfaces/ConversationState.html +3152 -0
- package/dist/docs/interfaces/CreateConversationOptions.html +3168 -0
- package/dist/docs/interfaces/LastMessage.html +3152 -0
- package/dist/docs/interfaces/Paginator.html +3243 -0
- package/dist/docs/interfaces/PushNotificationData.html +3168 -0
- package/dist/docs/interfaces/SendEmailOptions.html +3136 -0
- package/dist/docs/interfaces/SendMediaOptions.html +3170 -0
- package/dist/docs/modules.html +3425 -0
- package/dist/lib.d.ts +1952 -0
- package/dist/lib.js +7873 -0
- package/dist/lib.js.map +1 -0
- package/dist/post-install.js +29 -0
- package/dist/react-native.js +4038 -0
- package/dist/react-native.js.map +1 -0
- package/dist/twilio-conversations.js +40912 -0
- package/dist/twilio-conversations.min.js +156 -0
- package/package.json +59 -48
- package/.circleci/config.yml +0 -650
- package/.deepsource.toml +0 -6
- package/.env.example +0 -13
- package/browser/aggregateddeliveryreceipt.js +0 -152
- package/browser/client.js +0 -991
- package/browser/configuration.js +0 -80
- package/browser/conversation.js +0 -1826
- package/browser/data/conversations.js +0 -632
- package/browser/data/messages.js +0 -522
- package/browser/data/participants.js +0 -411
- package/browser/data/users.js +0 -281
- package/browser/detaileddeliveryreceipt.js +0 -44
- package/browser/index.js +0 -4
- package/browser/interfaces/limits.js +0 -3
- package/browser/interfaces/notificationtypes.js +0 -21
- package/browser/interfaces/paginator.js +0 -53
- package/browser/interfaces/responsecodes.js +0 -20
- package/browser/interfaces/transport.js +0 -3
- package/browser/logger.js +0 -141
- package/browser/media.js +0 -198
- package/browser/message.js +0 -685
- package/browser/participant.js +0 -415
- package/browser/pushnotification.js +0 -49
- package/browser/restpaginator.js +0 -74
- package/browser/services/network.js +0 -223
- package/browser/services/readhorizon.js +0 -181
- package/browser/services/typingindicator.js +0 -142
- package/browser/session.js +0 -505
- package/browser/sessionerror.js +0 -93
- package/browser/sri.json +0 -1
- package/browser/synclist.js +0 -90
- package/browser/synclistdescriptor.js +0 -29
- package/browser/syncpaginator.js +0 -63
- package/browser/user.js +0 -431
- package/browser/util/deferred.js +0 -56
- package/browser/util/index.js +0 -108
- package/dist/@twilio/conversations.js +0 -35533
- package/dist/@twilio/conversations.min.js +0 -204
- package/dist/docs/AggregatedDeliveryReceipt.html +0 -948
- package/dist/docs/Client.html +0 -5075
- package/dist/docs/Conversation.html +0 -6018
- package/dist/docs/DetailedDeliveryReceipt.html +0 -641
- package/dist/docs/Media.html +0 -694
- package/dist/docs/Message.html +0 -1934
- package/dist/docs/Paginator.html +0 -605
- package/dist/docs/Participant.html +0 -1510
- package/dist/docs/PushNotification.html +0 -836
- package/dist/docs/SessionError.html +0 -379
- package/dist/docs/User.html +0 -1315
- package/dist/docs/classes.list.html +0 -4431
- package/dist/docs/fonts/glyphicons-halflings-regular.eot +0 -0
- package/dist/docs/fonts/glyphicons-halflings-regular.svg +0 -288
- package/dist/docs/fonts/glyphicons-halflings-regular.ttf +0 -0
- package/dist/docs/fonts/glyphicons-halflings-regular.woff +0 -0
- package/dist/docs/fonts/glyphicons-halflings-regular.woff2 +0 -0
- package/dist/docs/img/glyphicons-halflings-white.png +0 -0
- package/dist/docs/img/glyphicons-halflings.png +0 -0
- package/dist/docs/quicksearch.html +0 -31
- package/dist/docs/scripts/docstrap.lib.js +0 -11
- package/dist/docs/scripts/fulltext-search-ui.js +0 -89
- package/dist/docs/scripts/fulltext-search.js +0 -36
- package/dist/docs/scripts/lunr.min.js +0 -6
- package/dist/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
- package/dist/docs/scripts/prettify/jquery.min.js +0 -6
- package/dist/docs/scripts/prettify/lang-css.js +0 -21
- package/dist/docs/scripts/prettify/prettify.js +0 -496
- package/dist/docs/scripts/sunlight.js +0 -1157
- package/dist/docs/scripts/toc.js +0 -203
- package/dist/docs/styles/darkstrap.css +0 -960
- package/dist/docs/styles/prettify-tomorrow.css +0 -132
- package/dist/docs/styles/site.cerulean.css +0 -7008
- package/dist/docs/styles/site.cosmo.css +0 -7061
- package/dist/docs/styles/site.cyborg.css +0 -7048
- package/dist/docs/styles/site.darkly.css +0 -7171
- package/dist/docs/styles/site.darkstrap.css +0 -5638
- package/dist/docs/styles/site.dibs-bootstrap.css +0 -5899
- package/dist/docs/styles/site.flatly.css +0 -7147
- package/dist/docs/styles/site.journal.css +0 -6973
- package/dist/docs/styles/site.lumen.css +0 -7298
- package/dist/docs/styles/site.paper.css +0 -7623
- package/dist/docs/styles/site.readable.css +0 -6997
- package/dist/docs/styles/site.sandstone.css +0 -7035
- package/dist/docs/styles/site.simplex.css +0 -7023
- package/dist/docs/styles/site.slate.css +0 -7343
- package/dist/docs/styles/site.spacelab.css +0 -7055
- package/dist/docs/styles/site.superhero.css +0 -7131
- package/dist/docs/styles/site.united.css +0 -6895
- package/dist/docs/styles/site.yeti.css +0 -7195
- package/dist/docs/styles/sunlight.dark.css +0 -345
- package/dist/docs/styles/sunlight.default.css +0 -344
- package/dist/sri.json +0 -1
- package/lib/aggregateddeliveryreceipt.d.ts +0 -98
- package/lib/aggregateddeliveryreceipt.js +0 -112
- package/lib/client.d.ts +0 -317
- package/lib/client.js +0 -633
- package/lib/configuration.d.ts +0 -21
- package/lib/configuration.js +0 -41
- package/lib/conversation.d.ts +0 -460
- package/lib/conversation.js +0 -940
- package/lib/data/conversations.d.ts +0 -57
- package/lib/data/conversations.js +0 -296
- package/lib/data/messages.d.ts +0 -75
- package/lib/data/messages.js +0 -208
- package/lib/data/participants.d.ts +0 -94
- package/lib/data/participants.js +0 -204
- package/lib/data/users.d.ts +0 -42
- package/lib/data/users.js +0 -113
- package/lib/detaileddeliveryreceipt.d.ts +0 -45
- package/lib/detaileddeliveryreceipt.js +0 -34
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -3
- package/lib/interfaces/limits.d.ts +0 -8
- package/lib/interfaces/limits.js +0 -2
- package/lib/interfaces/notificationtypes.d.ts +0 -8
- package/lib/interfaces/notificationtypes.js +0 -11
- package/lib/interfaces/paginator.d.ts +0 -52
- package/lib/interfaces/paginator.js +0 -28
- package/lib/interfaces/responsecodes.d.ts +0 -8
- package/lib/interfaces/responsecodes.js +0 -10
- package/lib/interfaces/transport.d.ts +0 -13
- package/lib/interfaces/transport.js +0 -2
- package/lib/logger.d.ts +0 -18
- package/lib/logger.js +0 -35
- package/lib/media.d.ts +0 -52
- package/lib/media.js +0 -69
- package/lib/message.d.ts +0 -136
- package/lib/message.js +0 -305
- package/lib/participant.d.ts +0 -142
- package/lib/participant.js +0 -219
- package/lib/pushnotification.d.ts +0 -48
- package/lib/pushnotification.js +0 -39
- package/lib/restpaginator.d.ts +0 -19
- package/lib/restpaginator.js +0 -36
- package/lib/services/network.d.ts +0 -22
- package/lib/services/network.js +0 -87
- package/lib/services/readhorizon.d.ts +0 -28
- package/lib/services/readhorizon.js +0 -112
- package/lib/services/typingindicator.d.ts +0 -50
- package/lib/services/typingindicator.js +0 -102
- package/lib/session.d.ts +0 -63
- package/lib/session.js +0 -213
- package/lib/sessionerror.d.ts +0 -12
- package/lib/sessionerror.js +0 -24
- package/lib/sri.json +0 -1
- package/lib/synclist.d.ts +0 -24
- package/lib/synclist.js +0 -28
- package/lib/synclistdescriptor.d.ts +0 -27
- package/lib/synclistdescriptor.js +0 -19
- package/lib/syncpaginator.d.ts +0 -22
- package/lib/syncpaginator.js +0 -37
- package/lib/user.d.ts +0 -98
- package/lib/user.js +0 -219
- package/lib/util/deferred.d.ts +0 -12
- package/lib/util/deferred.js +0 -22
- package/lib/util/index.d.ts +0 -28
- package/lib/util/index.js +0 -82
- package/tools/rtd-sdk-cdn-pin/.gitrepo +0 -12
- package/tools/rtd-sdk-cdn-pin/README.md +0 -54
- package/tools/rtd-sdk-cdn-pin/bintray-settings.xml.template +0 -16
- package/tools/rtd-sdk-cdn-pin/cdn-common/cdn-prepare.sh +0 -67
- package/tools/rtd-sdk-cdn-pin/cdn-pin-latest.sh +0 -19
- package/tools/rtd-sdk-cdn-pin/cdn-pin.sh +0 -19
- package/tools/rtd-sdk-cdn-pin/cdn-upload.sh +0 -13
- package/tools/rtd-sdk-cdn-pin/fetch/common/fetch-bintray-android.sh +0 -34
- package/tools/rtd-sdk-cdn-pin/fetch/common/fetch-npm.sh +0 -18
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-chat-android.sh +0 -5
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-chat-js.sh +0 -5
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-conversations-android.sh +0 -6
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-conversations-js.sh +0 -5
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-sync-android.sh +0 -5
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-sync-js.sh +0 -5
- package/tools/rtd-sdk-cdn-pin/fetch-artifact.sh +0 -26
- package/tools/sdk-release-tool/.gitrepo +0 -12
- package/tools/sdk-release-tool/Makefile +0 -49
- package/tools/sdk-release-tool/README.md +0 -275
- package/tools/sdk-release-tool/delete +0 -3
- package/tools/sdk-release-tool/download +0 -3
- package/tools/sdk-release-tool/get-cors +0 -3
- package/tools/sdk-release-tool/list +0 -3
- package/tools/sdk-release-tool/pin +0 -3
- package/tools/sdk-release-tool/pin-latest +0 -3
- package/tools/sdk-release-tool/requirements.txt +0 -4
- package/tools/sdk-release-tool/sdk-release-tool +0 -3
- package/tools/sdk-release-tool/sdk_release_tools/__init__.py +0 -0
- package/tools/sdk-release-tool/sdk_release_tools/__main__.py +0 -110
- package/tools/sdk-release-tool/sdk_release_tools/aws.py +0 -70
- package/tools/sdk-release-tool/sdk_release_tools/cli.py +0 -181
- package/tools/sdk-release-tool/sdk_release_tools/log.py +0 -24
- package/tools/sdk-release-tool/sdk_release_tools/ops.py +0 -295
- package/tools/sdk-release-tool/sdk_release_tools/rpm.py +0 -28
- package/tools/sdk-release-tool/sdk_release_tools/util.py +0 -186
- package/tools/sdk-release-tool/sdk_release_tools/versions.py +0 -362
- package/tools/sdk-release-tool/signal-sdk-js.json +0 -28
- package/tools/sdk-release-tool/tests/test_versions.py +0 -94
- package/tools/sdk-release-tool/twilio-accessmanager-android.json +0 -19
- package/tools/sdk-release-tool/twilio-accessmanager-ios.json +0 -26
- package/tools/sdk-release-tool/twilio-auth-ios.json +0 -29
- package/tools/sdk-release-tool/twilio-authenticator-ios.json +0 -29
- package/tools/sdk-release-tool/twilio-chat-android-2.json +0 -19
- package/tools/sdk-release-tool/twilio-chat-android.json +0 -22
- package/tools/sdk-release-tool/twilio-chat-ios.json +0 -26
- package/tools/sdk-release-tool/twilio-chat-js.json +0 -27
- package/tools/sdk-release-tool/twilio-client-android-aar.json +0 -22
- package/tools/sdk-release-tool/twilio-client-android.json +0 -22
- package/tools/sdk-release-tool/twilio-client-ios.json +0 -20
- package/tools/sdk-release-tool/twilio-client-js.json +0 -17
- package/tools/sdk-release-tool/twilio-client-sounds-js.json +0 -14
- package/tools/sdk-release-tool/twilio-common-android-maven.json +0 -16
- package/tools/sdk-release-tool/twilio-common-android.json +0 -22
- package/tools/sdk-release-tool/twilio-common-ios-rtc.json +0 -25
- package/tools/sdk-release-tool/twilio-common-ios.json +0 -25
- package/tools/sdk-release-tool/twilio-common-js.json +0 -19
- package/tools/sdk-release-tool/twilio-conversations-android.json +0 -22
- package/tools/sdk-release-tool/twilio-conversations-ios.json +0 -26
- package/tools/sdk-release-tool/twilio-conversations-js.json +0 -27
- package/tools/sdk-release-tool/twilio-flex-js.json +0 -20
- package/tools/sdk-release-tool/twilio-flex-webchat-js.json +0 -16
- package/tools/sdk-release-tool/twilio-frame-chat-android.json +0 -22
- package/tools/sdk-release-tool/twilio-frame-chat-ios.json +0 -23
- package/tools/sdk-release-tool/twilio-frame-chat-js.json +0 -23
- package/tools/sdk-release-tool/twilio-ip-messaging-android-maven.json +0 -16
- package/tools/sdk-release-tool/twilio-ip-messaging-android.json +0 -22
- package/tools/sdk-release-tool/twilio-ip-messaging-ios.json +0 -25
- package/tools/sdk-release-tool/twilio-ip-messaging-js.json +0 -21
- package/tools/sdk-release-tool/twilio-sync-android.json +0 -22
- package/tools/sdk-release-tool/twilio-sync-ios.json +0 -26
- package/tools/sdk-release-tool/twilio-sync-js.json +0 -39
- package/tools/sdk-release-tool/twilio-taskrouter-js.json +0 -17
- package/tools/sdk-release-tool/twilio-video-android.json +0 -22
- package/tools/sdk-release-tool/twilio-video-cpp-linux-cross-rootfs.json +0 -13
- package/tools/sdk-release-tool/twilio-video-cpp.json +0 -33
- package/tools/sdk-release-tool/twilio-video-ios.json +0 -25
- package/tools/sdk-release-tool/twilio-video-js.json +0 -19
- package/tools/sdk-release-tool/twilio-video-jsdocs.json +0 -14
- package/tools/sdk-release-tool/twilio-voice-android.json +0 -22
- package/tools/sdk-release-tool/twilio-voice-ios.json +0 -29
- package/tools/sdk-release-tool/unpin +0 -3
- package/tools/sdk-release-tool/unpin-latest +0 -3
- package/tools/sdk-release-tool/upload +0 -3
- package/twilio-chat.js.iml +0 -9
@@ -1,1157 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Sunlight
|
3
|
-
* Intelligent syntax highlighting
|
4
|
-
*
|
5
|
-
* http://sunlightjs.com/
|
6
|
-
*
|
7
|
-
* by Tommy Montgomery <http://tmont.com>
|
8
|
-
* Licensed under WTFPL <http://sam.zoy.org/wtfpl/>
|
9
|
-
*/
|
10
|
-
(function(window, document, undefined){
|
11
|
-
|
12
|
-
var
|
13
|
-
//http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html
|
14
|
-
//we have to sniff this because IE requires \r
|
15
|
-
isIe = !+"\v1",
|
16
|
-
EOL = isIe ? "\r" : "\n",
|
17
|
-
EMPTY = function() { return null; },
|
18
|
-
HIGHLIGHTED_NODE_COUNT = 0,
|
19
|
-
DEFAULT_LANGUAGE = "plaintext",
|
20
|
-
DEFAULT_CLASS_PREFIX = "sunlight-",
|
21
|
-
|
22
|
-
//global sunlight variables
|
23
|
-
defaultAnalyzer,
|
24
|
-
getComputedStyle,
|
25
|
-
globalOptions = {
|
26
|
-
tabWidth: 4,
|
27
|
-
classPrefix: DEFAULT_CLASS_PREFIX,
|
28
|
-
showWhitespace: false,
|
29
|
-
maxHeight: false
|
30
|
-
},
|
31
|
-
languages = {},
|
32
|
-
languageDefaults = {},
|
33
|
-
events = {
|
34
|
-
beforeHighlightNode: [],
|
35
|
-
beforeHighlight: [],
|
36
|
-
beforeTokenize: [],
|
37
|
-
afterTokenize: [],
|
38
|
-
beforeAnalyze: [],
|
39
|
-
afterAnalyze: [],
|
40
|
-
afterHighlight: [],
|
41
|
-
afterHighlightNode: []
|
42
|
-
};
|
43
|
-
|
44
|
-
defaultAnalyzer = (function() {
|
45
|
-
function defaultHandleToken(suffix) {
|
46
|
-
return function(context) {
|
47
|
-
var element = document.createElement("span");
|
48
|
-
element.className = context.options.classPrefix + suffix;
|
49
|
-
element.appendChild(context.createTextNode(context.tokens[context.index]));
|
50
|
-
return context.addNode(element) || true;
|
51
|
-
};
|
52
|
-
}
|
53
|
-
|
54
|
-
return {
|
55
|
-
handleToken: function(context) {
|
56
|
-
return defaultHandleToken(context.tokens[context.index].name)(context);
|
57
|
-
},
|
58
|
-
|
59
|
-
//just append default content as a text node
|
60
|
-
handle_default: function(context) {
|
61
|
-
return context.addNode(context.createTextNode(context.tokens[context.index]));
|
62
|
-
},
|
63
|
-
|
64
|
-
//this handles the named ident mayhem
|
65
|
-
handle_ident: function(context) {
|
66
|
-
var evaluate = function(rules, createRule) {
|
67
|
-
var i;
|
68
|
-
rules = rules || [];
|
69
|
-
for (i = 0; i < rules.length; i++) {
|
70
|
-
if (typeof(rules[i]) === "function") {
|
71
|
-
if (rules[i](context)) {
|
72
|
-
return defaultHandleToken("named-ident")(context);
|
73
|
-
}
|
74
|
-
} else if (createRule && createRule(rules[i])(context.tokens)) {
|
75
|
-
return defaultHandleToken("named-ident")(context);
|
76
|
-
}
|
77
|
-
}
|
78
|
-
|
79
|
-
return false;
|
80
|
-
};
|
81
|
-
|
82
|
-
return evaluate(context.language.namedIdentRules.custom)
|
83
|
-
|| evaluate(context.language.namedIdentRules.follows, function(ruleData) { return createProceduralRule(context.index - 1, -1, ruleData, context.language.caseInsensitive); })
|
84
|
-
|| evaluate(context.language.namedIdentRules.precedes, function(ruleData) { return createProceduralRule(context.index + 1, 1, ruleData, context.language.caseInsensitive); })
|
85
|
-
|| evaluate(context.language.namedIdentRules.between, function(ruleData) { return createBetweenRule(context.index, ruleData.opener, ruleData.closer, context.language.caseInsensitive); })
|
86
|
-
|| defaultHandleToken("ident")(context);
|
87
|
-
}
|
88
|
-
};
|
89
|
-
}());
|
90
|
-
|
91
|
-
languageDefaults = {
|
92
|
-
analyzer: create(defaultAnalyzer),
|
93
|
-
customTokens: [],
|
94
|
-
namedIdentRules: {},
|
95
|
-
punctuation: /[^\w\s]/,
|
96
|
-
numberParser: defaultNumberParser,
|
97
|
-
caseInsensitive: false,
|
98
|
-
doNotParse: /\s/,
|
99
|
-
contextItems: {},
|
100
|
-
embeddedLanguages: {}
|
101
|
-
};
|
102
|
-
|
103
|
-
//adapted from http://blargh.tommymontgomery.com/2010/04/get-computed-style-in-javascript/
|
104
|
-
getComputedStyle = (function() {
|
105
|
-
var func = null;
|
106
|
-
if (document.defaultView && document.defaultView.getComputedStyle) {
|
107
|
-
func = document.defaultView.getComputedStyle;
|
108
|
-
} else {
|
109
|
-
func = function(element, anything) {
|
110
|
-
return element["currentStyle"] || {};
|
111
|
-
};
|
112
|
-
}
|
113
|
-
|
114
|
-
return function(element, style) {
|
115
|
-
return func(element, null)[style];
|
116
|
-
}
|
117
|
-
}());
|
118
|
-
|
119
|
-
//-----------
|
120
|
-
//FUNCTIONS
|
121
|
-
//-----------
|
122
|
-
|
123
|
-
function createCodeReader(text) {
|
124
|
-
var index = 0,
|
125
|
-
line = 1,
|
126
|
-
column = 1,
|
127
|
-
length,
|
128
|
-
EOF = undefined,
|
129
|
-
currentChar,
|
130
|
-
nextReadBeginsLine;
|
131
|
-
|
132
|
-
text = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n"); //normalize line endings to unix
|
133
|
-
|
134
|
-
length = text.length;
|
135
|
-
currentChar = length > 0 ? text.charAt(0) : EOF;
|
136
|
-
|
137
|
-
function getCharacters(count) {
|
138
|
-
var value;
|
139
|
-
if (count === 0) {
|
140
|
-
return "";
|
141
|
-
}
|
142
|
-
|
143
|
-
count = count || 1;
|
144
|
-
|
145
|
-
value = text.substring(index + 1, index + count + 1);
|
146
|
-
return value === "" ? EOF : value;
|
147
|
-
}
|
148
|
-
|
149
|
-
return {
|
150
|
-
toString: function() {
|
151
|
-
return "length: " + length + ", index: " + index + ", line: " + line + ", column: " + column + ", current: [" + currentChar + "]";
|
152
|
-
},
|
153
|
-
|
154
|
-
peek: function(count) {
|
155
|
-
return getCharacters(count);
|
156
|
-
},
|
157
|
-
|
158
|
-
substring: function() {
|
159
|
-
return text.substring(index);
|
160
|
-
},
|
161
|
-
|
162
|
-
peekSubstring: function() {
|
163
|
-
return text.substring(index + 1);
|
164
|
-
},
|
165
|
-
|
166
|
-
read: function(count) {
|
167
|
-
var value = getCharacters(count),
|
168
|
-
newlineCount,
|
169
|
-
lastChar;
|
170
|
-
|
171
|
-
if (value === "") {
|
172
|
-
//this is a result of reading/peeking/doing nothing
|
173
|
-
return value;
|
174
|
-
}
|
175
|
-
|
176
|
-
if (value !== EOF) {
|
177
|
-
//advance index
|
178
|
-
index += value.length;
|
179
|
-
column += value.length;
|
180
|
-
|
181
|
-
//update line count
|
182
|
-
if (nextReadBeginsLine) {
|
183
|
-
line++;
|
184
|
-
column = 1;
|
185
|
-
nextReadBeginsLine = false;
|
186
|
-
}
|
187
|
-
|
188
|
-
newlineCount = value.substring(0, value.length - 1).replace(/[^\n]/g, "").length;
|
189
|
-
if (newlineCount > 0) {
|
190
|
-
line += newlineCount;
|
191
|
-
column = 1;
|
192
|
-
}
|
193
|
-
|
194
|
-
lastChar = last(value);
|
195
|
-
if (lastChar === "\n") {
|
196
|
-
nextReadBeginsLine = true;
|
197
|
-
}
|
198
|
-
|
199
|
-
currentChar = lastChar;
|
200
|
-
} else {
|
201
|
-
index = length;
|
202
|
-
currentChar = EOF;
|
203
|
-
}
|
204
|
-
|
205
|
-
return value;
|
206
|
-
},
|
207
|
-
|
208
|
-
text: function() { return text; },
|
209
|
-
|
210
|
-
getLine: function() { return line; },
|
211
|
-
getColumn: function() { return column; },
|
212
|
-
isEof: function() { return index >= length; },
|
213
|
-
isSol: function() { return column === 1; },
|
214
|
-
isSolWs: function() {
|
215
|
-
var temp = index,
|
216
|
-
c;
|
217
|
-
if (column === 1) {
|
218
|
-
return true;
|
219
|
-
}
|
220
|
-
|
221
|
-
//look backward until we find a newline or a non-whitespace character
|
222
|
-
while ((c = text.charAt(--temp)) !== "") {
|
223
|
-
if (c === "\n") {
|
224
|
-
return true;
|
225
|
-
}
|
226
|
-
if (!/\s/.test(c)) {
|
227
|
-
return false;
|
228
|
-
}
|
229
|
-
}
|
230
|
-
|
231
|
-
return true;
|
232
|
-
},
|
233
|
-
isEol: function() { return nextReadBeginsLine; },
|
234
|
-
EOF: EOF,
|
235
|
-
current: function() { return currentChar; }
|
236
|
-
};
|
237
|
-
}
|
238
|
-
|
239
|
-
//http://javascript.crockford.com/prototypal.html
|
240
|
-
function create(o) {
|
241
|
-
function F() {}
|
242
|
-
F.prototype = o;
|
243
|
-
return new F();
|
244
|
-
}
|
245
|
-
|
246
|
-
function appendAll(parent, children) {
|
247
|
-
var i;
|
248
|
-
for (i = 0; i < children.length; i++) {
|
249
|
-
parent.appendChild(children[i]);
|
250
|
-
}
|
251
|
-
}
|
252
|
-
|
253
|
-
//gets the last character in a string or the last element in an array
|
254
|
-
function last(thing) {
|
255
|
-
return thing.charAt ? thing.charAt(thing.length - 1) : thing[thing.length - 1];
|
256
|
-
}
|
257
|
-
|
258
|
-
//array.contains()
|
259
|
-
function contains(arr, value, caseInsensitive) {
|
260
|
-
var i;
|
261
|
-
if (arr.indexOf && !caseInsensitive) {
|
262
|
-
return arr.indexOf(value) >= 0;
|
263
|
-
}
|
264
|
-
|
265
|
-
for (i = 0; i < arr.length; i++) {
|
266
|
-
if (arr[i] === value) {
|
267
|
-
return true;
|
268
|
-
}
|
269
|
-
|
270
|
-
if (caseInsensitive && typeof(arr[i]) === "string" && typeof(value) === "string" && arr[i].toUpperCase() === value.toUpperCase()) {
|
271
|
-
return true;
|
272
|
-
}
|
273
|
-
}
|
274
|
-
|
275
|
-
return false;
|
276
|
-
}
|
277
|
-
|
278
|
-
//non-recursively merges one object into the other
|
279
|
-
function merge(defaultObject, objectToMerge) {
|
280
|
-
var key;
|
281
|
-
if (!objectToMerge) {
|
282
|
-
return defaultObject;
|
283
|
-
}
|
284
|
-
|
285
|
-
for (key in objectToMerge) {
|
286
|
-
defaultObject[key] = objectToMerge[key];
|
287
|
-
}
|
288
|
-
|
289
|
-
return defaultObject;
|
290
|
-
}
|
291
|
-
|
292
|
-
function clone(object) {
|
293
|
-
return merge({}, object);
|
294
|
-
}
|
295
|
-
|
296
|
-
//http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript/3561711#3561711
|
297
|
-
function regexEscape(s) {
|
298
|
-
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
|
299
|
-
}
|
300
|
-
|
301
|
-
function createProceduralRule(startIndex, direction, tokenRequirements, caseInsensitive) {
|
302
|
-
tokenRequirements = tokenRequirements.slice(0);
|
303
|
-
return function(tokens) {
|
304
|
-
var tokenIndexStart = startIndex,
|
305
|
-
j,
|
306
|
-
expected,
|
307
|
-
actual;
|
308
|
-
|
309
|
-
if (direction === 1) {
|
310
|
-
tokenRequirements.reverse();
|
311
|
-
}
|
312
|
-
|
313
|
-
for (j = 0; j < tokenRequirements.length; j++) {
|
314
|
-
actual = tokens[tokenIndexStart + (j * direction)];
|
315
|
-
expected = tokenRequirements[tokenRequirements.length - 1 - j];
|
316
|
-
|
317
|
-
if (actual === undefined) {
|
318
|
-
if (expected["optional"] !== undefined && expected.optional) {
|
319
|
-
tokenIndexStart -= direction;
|
320
|
-
} else {
|
321
|
-
return false;
|
322
|
-
}
|
323
|
-
} else if (actual.name === expected.token && (expected["values"] === undefined || contains(expected.values, actual.value, caseInsensitive))) {
|
324
|
-
//derp
|
325
|
-
continue;
|
326
|
-
} else if (expected["optional"] !== undefined && expected.optional) {
|
327
|
-
tokenIndexStart -= direction; //we need to reevaluate against this token again
|
328
|
-
} else {
|
329
|
-
return false;
|
330
|
-
}
|
331
|
-
}
|
332
|
-
|
333
|
-
return true;
|
334
|
-
};
|
335
|
-
}
|
336
|
-
|
337
|
-
function createBetweenRule(startIndex, opener, closer, caseInsensitive) {
|
338
|
-
return function(tokens) {
|
339
|
-
var index = startIndex,
|
340
|
-
token,
|
341
|
-
success = false;
|
342
|
-
|
343
|
-
//check to the left: if we run into a closer or never run into an opener, fail
|
344
|
-
while ((token = tokens[--index]) !== undefined) {
|
345
|
-
if (token.name === closer.token && contains(closer.values, token.value)) {
|
346
|
-
if (token.name === opener.token && contains(opener.values, token.value, caseInsensitive)) {
|
347
|
-
//if the closer is the same as the opener that's okay
|
348
|
-
success = true;
|
349
|
-
break;
|
350
|
-
}
|
351
|
-
|
352
|
-
return false;
|
353
|
-
}
|
354
|
-
|
355
|
-
if (token.name === opener.token && contains(opener.values, token.value, caseInsensitive)) {
|
356
|
-
success = true;
|
357
|
-
break;
|
358
|
-
}
|
359
|
-
}
|
360
|
-
|
361
|
-
if (!success) {
|
362
|
-
return false;
|
363
|
-
}
|
364
|
-
|
365
|
-
//check to the right for the closer
|
366
|
-
index = startIndex;
|
367
|
-
while ((token = tokens[++index]) !== undefined) {
|
368
|
-
if (token.name === opener.token && contains(opener.values, token.value, caseInsensitive)) {
|
369
|
-
if (token.name === closer.token && contains(closer.values, token.value, caseInsensitive)) {
|
370
|
-
//if the closer is the same as the opener that's okay
|
371
|
-
success = true;
|
372
|
-
break;
|
373
|
-
}
|
374
|
-
|
375
|
-
return false;
|
376
|
-
}
|
377
|
-
|
378
|
-
if (token.name === closer.token && contains(closer.values, token.value, caseInsensitive)) {
|
379
|
-
success = true;
|
380
|
-
break;
|
381
|
-
}
|
382
|
-
}
|
383
|
-
|
384
|
-
return success;
|
385
|
-
};
|
386
|
-
}
|
387
|
-
|
388
|
-
function matchWord(context, wordMap, tokenName, doNotRead) {
|
389
|
-
var current = context.reader.current(),
|
390
|
-
i,
|
391
|
-
word,
|
392
|
-
peek,
|
393
|
-
line = context.reader.getLine(),
|
394
|
-
column = context.reader.getColumn();
|
395
|
-
|
396
|
-
wordMap = wordMap || [];
|
397
|
-
if (context.language.caseInsensitive) {
|
398
|
-
current = current.toUpperCase();
|
399
|
-
}
|
400
|
-
|
401
|
-
if (!wordMap[current]) {
|
402
|
-
return null;
|
403
|
-
}
|
404
|
-
|
405
|
-
wordMap = wordMap[current];
|
406
|
-
for (i = 0; i < wordMap.length; i++) {
|
407
|
-
word = wordMap[i].value;
|
408
|
-
|
409
|
-
peek = current + context.reader.peek(word.length);
|
410
|
-
if (word === peek || wordMap[i].regex.test(peek)) {
|
411
|
-
return context.createToken(
|
412
|
-
tokenName,
|
413
|
-
context.reader.current() + context.reader[doNotRead ? "peek" : "read"](word.length - 1),
|
414
|
-
line,
|
415
|
-
column
|
416
|
-
);
|
417
|
-
}
|
418
|
-
}
|
419
|
-
|
420
|
-
return null;
|
421
|
-
}
|
422
|
-
|
423
|
-
//gets the next token in the specified direction while matcher matches the current token
|
424
|
-
function getNextWhile(tokens, index, direction, matcher) {
|
425
|
-
var count = 1,
|
426
|
-
token;
|
427
|
-
|
428
|
-
direction = direction || 1;
|
429
|
-
while (token = tokens[index + (direction * count++)]) {
|
430
|
-
if (!matcher(token)) {
|
431
|
-
return token;
|
432
|
-
}
|
433
|
-
}
|
434
|
-
|
435
|
-
return undefined;
|
436
|
-
}
|
437
|
-
|
438
|
-
//this is crucial for performance
|
439
|
-
function createHashMap(wordMap, boundary, caseInsensitive) {
|
440
|
-
//creates a hash table where the hash is the first character of the word
|
441
|
-
var newMap = { },
|
442
|
-
i,
|
443
|
-
word,
|
444
|
-
firstChar;
|
445
|
-
|
446
|
-
for (i = 0; i < wordMap.length; i++) {
|
447
|
-
word = caseInsensitive ? wordMap[i].toUpperCase() : wordMap[i];
|
448
|
-
firstChar = word.charAt(0);
|
449
|
-
if (!newMap[firstChar]) {
|
450
|
-
newMap[firstChar] = [];
|
451
|
-
}
|
452
|
-
|
453
|
-
newMap[firstChar].push({ value: word, regex: new RegExp("^" + regexEscape(word) + boundary, caseInsensitive ? "i" : "") });
|
454
|
-
}
|
455
|
-
|
456
|
-
return newMap;
|
457
|
-
}
|
458
|
-
|
459
|
-
function defaultNumberParser(context) {
|
460
|
-
var current = context.reader.current(),
|
461
|
-
number,
|
462
|
-
line = context.reader.getLine(),
|
463
|
-
column = context.reader.getColumn(),
|
464
|
-
allowDecimal = true,
|
465
|
-
peek;
|
466
|
-
|
467
|
-
if (!/\d/.test(current)) {
|
468
|
-
//is it a decimal followed by a number?
|
469
|
-
if (current !== "." || !/\d/.test(context.reader.peek())) {
|
470
|
-
return null;
|
471
|
-
}
|
472
|
-
|
473
|
-
//decimal without leading zero
|
474
|
-
number = current + context.reader.read();
|
475
|
-
allowDecimal = false;
|
476
|
-
} else {
|
477
|
-
number = current;
|
478
|
-
if (current === "0" && context.reader.peek() !== ".") {
|
479
|
-
//hex or octal
|
480
|
-
allowDecimal = false;
|
481
|
-
}
|
482
|
-
}
|
483
|
-
|
484
|
-
//easy way out: read until it's not a number or letter
|
485
|
-
//this will work for hex (0xef), octal (012), decimal and scientific notation (1e3)
|
486
|
-
//anything else and you're on your own
|
487
|
-
|
488
|
-
while ((peek = context.reader.peek()) !== context.reader.EOF) {
|
489
|
-
if (!/[A-Za-z0-9]/.test(peek)) {
|
490
|
-
if (peek === "." && allowDecimal && /\d$/.test(context.reader.peek(2))) {
|
491
|
-
number += context.reader.read();
|
492
|
-
allowDecimal = false;
|
493
|
-
continue;
|
494
|
-
}
|
495
|
-
|
496
|
-
break;
|
497
|
-
}
|
498
|
-
|
499
|
-
number += context.reader.read();
|
500
|
-
}
|
501
|
-
|
502
|
-
return context.createToken("number", number, line, column);
|
503
|
-
}
|
504
|
-
|
505
|
-
function fireEvent(eventName, highlighter, eventContext) {
|
506
|
-
var delegates = events[eventName] || [],
|
507
|
-
i;
|
508
|
-
|
509
|
-
for (i = 0; i < delegates.length; i++) {
|
510
|
-
delegates[i].call(highlighter, eventContext);
|
511
|
-
}
|
512
|
-
}
|
513
|
-
|
514
|
-
function Highlighter(options) {
|
515
|
-
this.options = merge(clone(globalOptions), options);
|
516
|
-
}
|
517
|
-
|
518
|
-
Highlighter.prototype = (function() {
|
519
|
-
var parseNextToken = (function() {
|
520
|
-
function isIdentMatch(context) {
|
521
|
-
return context.language.identFirstLetter && context.language.identFirstLetter.test(context.reader.current());
|
522
|
-
}
|
523
|
-
|
524
|
-
//token parsing functions
|
525
|
-
function parseKeyword(context) {
|
526
|
-
return matchWord(context, context.language.keywords, "keyword");
|
527
|
-
}
|
528
|
-
|
529
|
-
function parseCustomTokens(context) {
|
530
|
-
var tokenName,
|
531
|
-
token;
|
532
|
-
if (context.language.customTokens === undefined) {
|
533
|
-
return null;
|
534
|
-
}
|
535
|
-
|
536
|
-
for (tokenName in context.language.customTokens) {
|
537
|
-
token = matchWord(context, context.language.customTokens[tokenName], tokenName);
|
538
|
-
if (token !== null) {
|
539
|
-
return token;
|
540
|
-
}
|
541
|
-
}
|
542
|
-
|
543
|
-
return null;
|
544
|
-
}
|
545
|
-
|
546
|
-
function parseOperator(context) {
|
547
|
-
return matchWord(context, context.language.operators, "operator");
|
548
|
-
}
|
549
|
-
|
550
|
-
function parsePunctuation(context) {
|
551
|
-
var current = context.reader.current();
|
552
|
-
if (context.language.punctuation.test(regexEscape(current))) {
|
553
|
-
return context.createToken("punctuation", current, context.reader.getLine(), context.reader.getColumn());
|
554
|
-
}
|
555
|
-
|
556
|
-
return null;
|
557
|
-
}
|
558
|
-
|
559
|
-
function parseIdent(context) {
|
560
|
-
var ident,
|
561
|
-
peek,
|
562
|
-
line = context.reader.getLine(),
|
563
|
-
column = context.reader.getColumn();
|
564
|
-
|
565
|
-
if (!isIdentMatch(context)) {
|
566
|
-
return null;
|
567
|
-
}
|
568
|
-
|
569
|
-
ident = context.reader.current();
|
570
|
-
while ((peek = context.reader.peek()) !== context.reader.EOF) {
|
571
|
-
if (!context.language.identAfterFirstLetter.test(peek)) {
|
572
|
-
break;
|
573
|
-
}
|
574
|
-
|
575
|
-
ident += context.reader.read();
|
576
|
-
}
|
577
|
-
|
578
|
-
return context.createToken("ident", ident, line, column);
|
579
|
-
}
|
580
|
-
|
581
|
-
function parseDefault(context) {
|
582
|
-
if (context.defaultData.text === "") {
|
583
|
-
//new default token
|
584
|
-
context.defaultData.line = context.reader.getLine();
|
585
|
-
context.defaultData.column = context.reader.getColumn();
|
586
|
-
}
|
587
|
-
|
588
|
-
context.defaultData.text += context.reader.current();
|
589
|
-
return null;
|
590
|
-
}
|
591
|
-
|
592
|
-
function parseScopes(context) {
|
593
|
-
var current = context.reader.current(),
|
594
|
-
tokenName,
|
595
|
-
specificScopes,
|
596
|
-
j,
|
597
|
-
opener,
|
598
|
-
line,
|
599
|
-
column,
|
600
|
-
continuation,
|
601
|
-
value;
|
602
|
-
|
603
|
-
for (tokenName in context.language.scopes) {
|
604
|
-
specificScopes = context.language.scopes[tokenName];
|
605
|
-
for (j = 0; j < specificScopes.length; j++) {
|
606
|
-
opener = specificScopes[j][0];
|
607
|
-
|
608
|
-
value = current + context.reader.peek(opener.length - 1);
|
609
|
-
|
610
|
-
if (opener !== value && (!context.language.caseInsensitive || value.toUpperCase() !== opener.toUpperCase())) {
|
611
|
-
continue;
|
612
|
-
}
|
613
|
-
|
614
|
-
line = context.reader.getLine(), column = context.reader.getColumn();
|
615
|
-
context.reader.read(opener.length - 1);
|
616
|
-
continuation = getScopeReaderFunction(specificScopes[j], tokenName);
|
617
|
-
return continuation(context, continuation, value, line, column);
|
618
|
-
}
|
619
|
-
}
|
620
|
-
|
621
|
-
return null;
|
622
|
-
}
|
623
|
-
|
624
|
-
function parseNumber(context) {
|
625
|
-
return context.language.numberParser(context);
|
626
|
-
}
|
627
|
-
|
628
|
-
function parseCustomRules(context) {
|
629
|
-
var customRules = context.language.customParseRules,
|
630
|
-
i,
|
631
|
-
token;
|
632
|
-
|
633
|
-
if (customRules === undefined) {
|
634
|
-
return null;
|
635
|
-
}
|
636
|
-
|
637
|
-
for (i = 0; i < customRules.length; i++) {
|
638
|
-
token = customRules[i](context);
|
639
|
-
if (token) {
|
640
|
-
return token;
|
641
|
-
}
|
642
|
-
}
|
643
|
-
|
644
|
-
return null;
|
645
|
-
}
|
646
|
-
|
647
|
-
return function(context) {
|
648
|
-
if (context.language.doNotParse.test(context.reader.current())) {
|
649
|
-
return parseDefault(context);
|
650
|
-
}
|
651
|
-
|
652
|
-
return parseCustomRules(context)
|
653
|
-
|| parseCustomTokens(context)
|
654
|
-
|| parseKeyword(context)
|
655
|
-
|| parseScopes(context)
|
656
|
-
|| parseIdent(context)
|
657
|
-
|| parseNumber(context)
|
658
|
-
|| parseOperator(context)
|
659
|
-
|| parsePunctuation(context)
|
660
|
-
|| parseDefault(context);
|
661
|
-
}
|
662
|
-
}());
|
663
|
-
|
664
|
-
function getScopeReaderFunction(scope, tokenName) {
|
665
|
-
var escapeSequences = scope[2] || [],
|
666
|
-
closerLength = scope[1].length,
|
667
|
-
closer = typeof(scope[1]) === "string" ? new RegExp(regexEscape(scope[1])) : scope[1].regex,
|
668
|
-
zeroWidth = scope[3] || false;
|
669
|
-
|
670
|
-
//processCurrent indicates that this is being called from a continuation
|
671
|
-
//which means that we need to process the current char, rather than peeking at the next
|
672
|
-
return function(context, continuation, buffer, line, column, processCurrent) {
|
673
|
-
var foundCloser = false;
|
674
|
-
buffer = buffer || "";
|
675
|
-
|
676
|
-
processCurrent = processCurrent ? 1 : 0;
|
677
|
-
|
678
|
-
function process(processCurrent) {
|
679
|
-
//check for escape sequences
|
680
|
-
var peekValue,
|
681
|
-
current = context.reader.current(),
|
682
|
-
i;
|
683
|
-
|
684
|
-
for (i = 0; i < escapeSequences.length; i++) {
|
685
|
-
peekValue = (processCurrent ? current : "") + context.reader.peek(escapeSequences[i].length - processCurrent);
|
686
|
-
if (peekValue === escapeSequences[i]) {
|
687
|
-
buffer += context.reader.read(peekValue.length - processCurrent);
|
688
|
-
return true;
|
689
|
-
}
|
690
|
-
}
|
691
|
-
|
692
|
-
peekValue = (processCurrent ? current : "") + context.reader.peek(closerLength - processCurrent);
|
693
|
-
if (closer.test(peekValue)) {
|
694
|
-
foundCloser = true;
|
695
|
-
return false;
|
696
|
-
}
|
697
|
-
|
698
|
-
buffer += processCurrent ? current : context.reader.read();
|
699
|
-
return true;
|
700
|
-
};
|
701
|
-
|
702
|
-
if (!processCurrent || process(true)) {
|
703
|
-
while (context.reader.peek() !== context.reader.EOF && process(false)) { }
|
704
|
-
}
|
705
|
-
|
706
|
-
if (processCurrent) {
|
707
|
-
buffer += context.reader.current();
|
708
|
-
context.reader.read();
|
709
|
-
} else {
|
710
|
-
buffer += zeroWidth || context.reader.peek() === context.reader.EOF ? "" : context.reader.read(closerLength);
|
711
|
-
}
|
712
|
-
|
713
|
-
if (!foundCloser) {
|
714
|
-
//we need to signal to the context that this scope was never properly closed
|
715
|
-
//this has significance for partial parses (e.g. for nested languages)
|
716
|
-
context.continuation = continuation;
|
717
|
-
}
|
718
|
-
|
719
|
-
return context.createToken(tokenName, buffer, line, column);
|
720
|
-
};
|
721
|
-
}
|
722
|
-
|
723
|
-
//called before processing the current
|
724
|
-
function switchToEmbeddedLanguageIfNecessary(context) {
|
725
|
-
var i,
|
726
|
-
embeddedLanguage;
|
727
|
-
|
728
|
-
for (i = 0; i < context.language.embeddedLanguages.length; i++) {
|
729
|
-
if (!languages[context.language.embeddedLanguages[i].language]) {
|
730
|
-
//unregistered language
|
731
|
-
continue;
|
732
|
-
}
|
733
|
-
|
734
|
-
embeddedLanguage = clone(context.language.embeddedLanguages[i]);
|
735
|
-
|
736
|
-
if (embeddedLanguage.switchTo(context)) {
|
737
|
-
embeddedLanguage.oldItems = clone(context.items);
|
738
|
-
context.embeddedLanguageStack.push(embeddedLanguage);
|
739
|
-
context.language = languages[embeddedLanguage.language];
|
740
|
-
context.items = merge(context.items, clone(context.language.contextItems));
|
741
|
-
break;
|
742
|
-
}
|
743
|
-
}
|
744
|
-
}
|
745
|
-
|
746
|
-
//called after processing the current
|
747
|
-
function switchBackFromEmbeddedLanguageIfNecessary(context) {
|
748
|
-
var current = last(context.embeddedLanguageStack),
|
749
|
-
lang;
|
750
|
-
|
751
|
-
if (current && current.switchBack(context)) {
|
752
|
-
context.language = languages[current.parentLanguage];
|
753
|
-
lang = context.embeddedLanguageStack.pop();
|
754
|
-
|
755
|
-
//restore old items
|
756
|
-
context.items = clone(lang.oldItems);
|
757
|
-
lang.oldItems = {};
|
758
|
-
}
|
759
|
-
}
|
760
|
-
|
761
|
-
function tokenize(unhighlightedCode, language, partialContext, options) {
|
762
|
-
var tokens = [],
|
763
|
-
context,
|
764
|
-
continuation,
|
765
|
-
token;
|
766
|
-
|
767
|
-
fireEvent("beforeTokenize", this, { code: unhighlightedCode, language: language });
|
768
|
-
context = {
|
769
|
-
reader: createCodeReader(unhighlightedCode),
|
770
|
-
language: language,
|
771
|
-
items: clone(language.contextItems),
|
772
|
-
token: function(index) { return tokens[index]; },
|
773
|
-
getAllTokens: function() { return tokens.slice(0); },
|
774
|
-
count: function() { return tokens.length; },
|
775
|
-
options: options,
|
776
|
-
embeddedLanguageStack: [],
|
777
|
-
|
778
|
-
defaultData: {
|
779
|
-
text: "",
|
780
|
-
line: 1,
|
781
|
-
column: 1
|
782
|
-
},
|
783
|
-
createToken: function(name, value, line, column) {
|
784
|
-
return {
|
785
|
-
name: name,
|
786
|
-
line: line,
|
787
|
-
value: isIe ? value.replace(/\n/g, "\r") : value,
|
788
|
-
column: column,
|
789
|
-
language: this.language.name
|
790
|
-
};
|
791
|
-
}
|
792
|
-
};
|
793
|
-
|
794
|
-
//if continuation is given, then we need to pick up where we left off from a previous parse
|
795
|
-
//basically it indicates that a scope was never closed, so we need to continue that scope
|
796
|
-
if (partialContext.continuation) {
|
797
|
-
continuation = partialContext.continuation;
|
798
|
-
partialContext.continuation = null;
|
799
|
-
tokens.push(continuation(context, continuation, "", context.reader.getLine(), context.reader.getColumn(), true));
|
800
|
-
}
|
801
|
-
|
802
|
-
while (!context.reader.isEof()) {
|
803
|
-
switchToEmbeddedLanguageIfNecessary(context);
|
804
|
-
token = parseNextToken(context);
|
805
|
-
|
806
|
-
//flush default data if needed (in pretty much all languages this is just whitespace)
|
807
|
-
if (token !== null) {
|
808
|
-
if (context.defaultData.text !== "") {
|
809
|
-
tokens.push(context.createToken("default", context.defaultData.text, context.defaultData.line, context.defaultData.column));
|
810
|
-
context.defaultData.text = "";
|
811
|
-
}
|
812
|
-
|
813
|
-
if (token[0] !== undefined) {
|
814
|
-
//multiple tokens
|
815
|
-
tokens = tokens.concat(token);
|
816
|
-
} else {
|
817
|
-
//single token
|
818
|
-
tokens.push(token);
|
819
|
-
}
|
820
|
-
}
|
821
|
-
|
822
|
-
switchBackFromEmbeddedLanguageIfNecessary(context);
|
823
|
-
context.reader.read();
|
824
|
-
}
|
825
|
-
|
826
|
-
//append the last default token, if necessary
|
827
|
-
if (context.defaultData.text !== "") {
|
828
|
-
tokens.push(context.createToken("default", context.defaultData.text, context.defaultData.line, context.defaultData.column));
|
829
|
-
}
|
830
|
-
|
831
|
-
fireEvent("afterTokenize", this, { code: unhighlightedCode, parserContext: context });
|
832
|
-
return context;
|
833
|
-
}
|
834
|
-
|
835
|
-
function createAnalyzerContext(parserContext, partialContext, options) {
|
836
|
-
var nodes = [],
|
837
|
-
prepareText = function() {
|
838
|
-
var nbsp, tab;
|
839
|
-
if (options.showWhitespace) {
|
840
|
-
nbsp = String.fromCharCode(0xB7);
|
841
|
-
tab = new Array(options.tabWidth).join(String.fromCharCode(0x2014)) + String.fromCharCode(0x2192);
|
842
|
-
} else {
|
843
|
-
nbsp = String.fromCharCode(0xA0);
|
844
|
-
tab = new Array(options.tabWidth + 1).join(nbsp);
|
845
|
-
}
|
846
|
-
|
847
|
-
return function(token) {
|
848
|
-
var value = token.value.split(" ").join(nbsp),
|
849
|
-
tabIndex,
|
850
|
-
lastNewlineColumn,
|
851
|
-
actualColumn,
|
852
|
-
tabLength;
|
853
|
-
|
854
|
-
//tabstop madness: replace \t with the appropriate number of characters, depending on the tabWidth option and its relative position in the line
|
855
|
-
while ((tabIndex = value.indexOf("\t")) >= 0) {
|
856
|
-
lastNewlineColumn = value.lastIndexOf(EOL, tabIndex);
|
857
|
-
actualColumn = lastNewlineColumn === -1 ? tabIndex : tabIndex - lastNewlineColumn - 1;
|
858
|
-
tabLength = options.tabWidth - (actualColumn % options.tabWidth); //actual length of the TAB character
|
859
|
-
|
860
|
-
value = value.substring(0, tabIndex) + tab.substring(options.tabWidth - tabLength) + value.substring(tabIndex + 1);
|
861
|
-
}
|
862
|
-
|
863
|
-
return value;
|
864
|
-
};
|
865
|
-
}();
|
866
|
-
|
867
|
-
return {
|
868
|
-
tokens: (partialContext.tokens || []).concat(parserContext.getAllTokens()),
|
869
|
-
index: partialContext.index ? partialContext.index + 1 : 0,
|
870
|
-
language: null,
|
871
|
-
getAnalyzer: EMPTY,
|
872
|
-
options: options,
|
873
|
-
continuation: parserContext.continuation,
|
874
|
-
addNode: function(node) { nodes.push(node); },
|
875
|
-
createTextNode: function(token) { return document.createTextNode(prepareText(token)); },
|
876
|
-
getNodes: function() { return nodes; },
|
877
|
-
resetNodes: function() { nodes = []; },
|
878
|
-
items: parserContext.items
|
879
|
-
};
|
880
|
-
}
|
881
|
-
|
882
|
-
//partialContext allows us to perform a partial parse, and then pick up where we left off at a later time
|
883
|
-
//this functionality enables nested highlights (language within a language, e.g. PHP within HTML followed by more PHP)
|
884
|
-
function highlightText(unhighlightedCode, languageId, partialContext) {
|
885
|
-
var language = languages[languageId],
|
886
|
-
analyzerContext;
|
887
|
-
|
888
|
-
partialContext = partialContext || { };
|
889
|
-
if (language === undefined) {
|
890
|
-
//use default language if one wasn't specified or hasn't been registered
|
891
|
-
language = languages[DEFAULT_LANGUAGE];
|
892
|
-
}
|
893
|
-
|
894
|
-
fireEvent("beforeHighlight", this, { code: unhighlightedCode, language: language, previousContext: partialContext });
|
895
|
-
|
896
|
-
analyzerContext = createAnalyzerContext(
|
897
|
-
tokenize.call(this, unhighlightedCode, language, partialContext, this.options),
|
898
|
-
partialContext,
|
899
|
-
this.options
|
900
|
-
);
|
901
|
-
|
902
|
-
analyze.call(this, analyzerContext, partialContext.index ? partialContext.index + 1 : 0);
|
903
|
-
|
904
|
-
fireEvent("afterHighlight", this, { analyzerContext: analyzerContext });
|
905
|
-
|
906
|
-
return analyzerContext;
|
907
|
-
}
|
908
|
-
|
909
|
-
function createContainer(ctx) {
|
910
|
-
var container = document.createElement("span");
|
911
|
-
container.className = ctx.options.classPrefix + ctx.language.name;
|
912
|
-
return container;
|
913
|
-
}
|
914
|
-
|
915
|
-
function analyze(analyzerContext, startIndex) {
|
916
|
-
var nodes,
|
917
|
-
lastIndex,
|
918
|
-
container,
|
919
|
-
i,
|
920
|
-
tokenName,
|
921
|
-
func,
|
922
|
-
language,
|
923
|
-
analyzer;
|
924
|
-
|
925
|
-
fireEvent("beforeAnalyze", this, { analyzerContext: analyzerContext });
|
926
|
-
|
927
|
-
if (analyzerContext.tokens.length > 0) {
|
928
|
-
analyzerContext.language = languages[analyzerContext.tokens[0].language] || languages[DEFAULT_LANGUAGE];;
|
929
|
-
nodes = [];
|
930
|
-
lastIndex = 0;
|
931
|
-
container = createContainer(analyzerContext);
|
932
|
-
|
933
|
-
for (i = startIndex; i < analyzerContext.tokens.length; i++) {
|
934
|
-
language = languages[analyzerContext.tokens[i].language] || languages[DEFAULT_LANGUAGE];
|
935
|
-
if (language.name !== analyzerContext.language.name) {
|
936
|
-
appendAll(container, analyzerContext.getNodes());
|
937
|
-
analyzerContext.resetNodes();
|
938
|
-
|
939
|
-
nodes.push(container);
|
940
|
-
analyzerContext.language = language;
|
941
|
-
container = createContainer(analyzerContext);
|
942
|
-
}
|
943
|
-
|
944
|
-
analyzerContext.index = i;
|
945
|
-
tokenName = analyzerContext.tokens[i].name;
|
946
|
-
func = "handle_" + tokenName;
|
947
|
-
|
948
|
-
analyzer = analyzerContext.getAnalyzer.call(analyzerContext) || analyzerContext.language.analyzer;
|
949
|
-
analyzer[func] ? analyzer[func](analyzerContext) : analyzer.handleToken(analyzerContext);
|
950
|
-
}
|
951
|
-
|
952
|
-
//append the last nodes, and add the final nodes to the context
|
953
|
-
appendAll(container, analyzerContext.getNodes());
|
954
|
-
nodes.push(container);
|
955
|
-
analyzerContext.resetNodes();
|
956
|
-
for (i = 0; i < nodes.length; i++) {
|
957
|
-
analyzerContext.addNode(nodes[i]);
|
958
|
-
}
|
959
|
-
}
|
960
|
-
|
961
|
-
fireEvent("afterAnalyze", this, { analyzerContext: analyzerContext });
|
962
|
-
}
|
963
|
-
|
964
|
-
return {
|
965
|
-
//matches the language of the node to highlight
|
966
|
-
matchSunlightNode: function() {
|
967
|
-
var regex;
|
968
|
-
|
969
|
-
return function(node) {
|
970
|
-
if (!regex) {
|
971
|
-
regex = new RegExp("(?:\\s|^)" + this.options.classPrefix + "highlight-(\\S+)(?:\\s|$)");
|
972
|
-
}
|
973
|
-
|
974
|
-
return regex.exec(node.className);
|
975
|
-
};
|
976
|
-
}(),
|
977
|
-
|
978
|
-
//determines if the node has already been highlighted
|
979
|
-
isAlreadyHighlighted: function() {
|
980
|
-
var regex;
|
981
|
-
return function(node) {
|
982
|
-
if (!regex) {
|
983
|
-
regex = new RegExp("(?:\\s|^)" + this.options.classPrefix + "highlighted(?:\\s|$)");
|
984
|
-
}
|
985
|
-
|
986
|
-
return regex.test(node.className);
|
987
|
-
};
|
988
|
-
}(),
|
989
|
-
|
990
|
-
//highlights a block of text
|
991
|
-
highlight: function(code, languageId) { return highlightText.call(this, code, languageId); },
|
992
|
-
|
993
|
-
//recursively highlights a DOM node
|
994
|
-
highlightNode: function highlightRecursive(node) {
|
995
|
-
var match,
|
996
|
-
languageId,
|
997
|
-
currentNodeCount,
|
998
|
-
j,
|
999
|
-
nodes,
|
1000
|
-
k,
|
1001
|
-
partialContext,
|
1002
|
-
container,
|
1003
|
-
codeContainer;
|
1004
|
-
|
1005
|
-
if (this.isAlreadyHighlighted(node) || (match = this.matchSunlightNode(node)) === null) {
|
1006
|
-
return;
|
1007
|
-
}
|
1008
|
-
|
1009
|
-
languageId = match[1];
|
1010
|
-
currentNodeCount = 0;
|
1011
|
-
fireEvent("beforeHighlightNode", this, { node: node });
|
1012
|
-
for (j = 0; j < node.childNodes.length; j++) {
|
1013
|
-
if (node.childNodes[j].nodeType === 3) {
|
1014
|
-
//text nodes
|
1015
|
-
partialContext = highlightText.call(this, node.childNodes[j].nodeValue, languageId, partialContext);
|
1016
|
-
HIGHLIGHTED_NODE_COUNT++;
|
1017
|
-
currentNodeCount = currentNodeCount || HIGHLIGHTED_NODE_COUNT;
|
1018
|
-
nodes = partialContext.getNodes();
|
1019
|
-
|
1020
|
-
node.replaceChild(nodes[0], node.childNodes[j]);
|
1021
|
-
for (k = 1; k < nodes.length; k++) {
|
1022
|
-
node.insertBefore(nodes[k], nodes[k - 1].nextSibling);
|
1023
|
-
}
|
1024
|
-
} else if (node.childNodes[j].nodeType === 1) {
|
1025
|
-
//element nodes
|
1026
|
-
highlightRecursive.call(this, node.childNodes[j]);
|
1027
|
-
}
|
1028
|
-
}
|
1029
|
-
|
1030
|
-
//indicate that this node has been highlighted
|
1031
|
-
node.className += " " + this.options.classPrefix + "highlighted";
|
1032
|
-
|
1033
|
-
//if the node is block level, we put it in a container, otherwise we just leave it alone
|
1034
|
-
if (getComputedStyle(node, "display") === "block") {
|
1035
|
-
container = document.createElement("div");
|
1036
|
-
container.className = this.options.classPrefix + "container";
|
1037
|
-
|
1038
|
-
codeContainer = document.createElement("div");
|
1039
|
-
codeContainer.className = this.options.classPrefix + "code-container";
|
1040
|
-
|
1041
|
-
//apply max height if specified in options
|
1042
|
-
if (this.options.maxHeight !== false) {
|
1043
|
-
codeContainer.style.overflowY = "auto";
|
1044
|
-
codeContainer.style.maxHeight = this.options.maxHeight + (/^\d+$/.test(this.options.maxHeight) ? "px" : "");
|
1045
|
-
}
|
1046
|
-
|
1047
|
-
container.appendChild(codeContainer);
|
1048
|
-
|
1049
|
-
node.parentNode.insertBefore(codeContainer, node);
|
1050
|
-
node.parentNode.removeChild(node);
|
1051
|
-
codeContainer.appendChild(node);
|
1052
|
-
|
1053
|
-
codeContainer.parentNode.insertBefore(container, codeContainer);
|
1054
|
-
codeContainer.parentNode.removeChild(codeContainer);
|
1055
|
-
container.appendChild(codeContainer);
|
1056
|
-
}
|
1057
|
-
|
1058
|
-
fireEvent("afterHighlightNode", this, {
|
1059
|
-
container: container,
|
1060
|
-
codeContainer: codeContainer,
|
1061
|
-
node: node,
|
1062
|
-
count: currentNodeCount
|
1063
|
-
});
|
1064
|
-
}
|
1065
|
-
};
|
1066
|
-
}());
|
1067
|
-
|
1068
|
-
//public facing object
|
1069
|
-
window.Sunlight = {
|
1070
|
-
version: "1.18",
|
1071
|
-
Highlighter: Highlighter,
|
1072
|
-
createAnalyzer: function() { return create(defaultAnalyzer); },
|
1073
|
-
globalOptions: globalOptions,
|
1074
|
-
|
1075
|
-
highlightAll: function(options) {
|
1076
|
-
var highlighter = new Highlighter(options),
|
1077
|
-
tags = document.getElementsByTagName("*"),
|
1078
|
-
i;
|
1079
|
-
|
1080
|
-
for (i = 0; i < tags.length; i++) {
|
1081
|
-
highlighter.highlightNode(tags[i]);
|
1082
|
-
}
|
1083
|
-
},
|
1084
|
-
|
1085
|
-
registerLanguage: function(languageId, languageData) {
|
1086
|
-
var tokenName,
|
1087
|
-
embeddedLanguages,
|
1088
|
-
languageName;
|
1089
|
-
|
1090
|
-
if (!languageId) {
|
1091
|
-
throw "Languages must be registered with an identifier, e.g. \"php\" for PHP";
|
1092
|
-
}
|
1093
|
-
|
1094
|
-
languageData = merge(merge({}, languageDefaults), languageData);
|
1095
|
-
languageData.name = languageId;
|
1096
|
-
|
1097
|
-
//transform keywords, operators and custom tokens into a hash map
|
1098
|
-
languageData.keywords = createHashMap(languageData.keywords || [], "\\b", languageData.caseInsensitive);
|
1099
|
-
languageData.operators = createHashMap(languageData.operators || [], "", languageData.caseInsensitive);
|
1100
|
-
for (tokenName in languageData.customTokens) {
|
1101
|
-
languageData.customTokens[tokenName] = createHashMap(
|
1102
|
-
languageData.customTokens[tokenName].values,
|
1103
|
-
languageData.customTokens[tokenName].boundary,
|
1104
|
-
languageData.caseInsensitive
|
1105
|
-
);
|
1106
|
-
}
|
1107
|
-
|
1108
|
-
//convert the embedded language object to an easier-to-use array
|
1109
|
-
embeddedLanguages = [];
|
1110
|
-
for (languageName in languageData.embeddedLanguages) {
|
1111
|
-
embeddedLanguages.push({
|
1112
|
-
parentLanguage: languageData.name,
|
1113
|
-
language: languageName,
|
1114
|
-
switchTo: languageData.embeddedLanguages[languageName].switchTo,
|
1115
|
-
switchBack: languageData.embeddedLanguages[languageName].switchBack
|
1116
|
-
});
|
1117
|
-
}
|
1118
|
-
|
1119
|
-
languageData.embeddedLanguages = embeddedLanguages;
|
1120
|
-
|
1121
|
-
languages[languageData.name] = languageData;
|
1122
|
-
},
|
1123
|
-
|
1124
|
-
isRegistered: function(languageId) { return languages[languageId] !== undefined; },
|
1125
|
-
|
1126
|
-
bind: function(event, callback) {
|
1127
|
-
if (!events[event]) {
|
1128
|
-
throw "Unknown event \"" + event + "\"";
|
1129
|
-
}
|
1130
|
-
|
1131
|
-
events[event].push(callback);
|
1132
|
-
},
|
1133
|
-
|
1134
|
-
util: {
|
1135
|
-
last: last,
|
1136
|
-
regexEscape: regexEscape,
|
1137
|
-
eol: EOL,
|
1138
|
-
clone: clone,
|
1139
|
-
escapeSequences: ["\\n", "\\t", "\\r", "\\\\", "\\v", "\\f"],
|
1140
|
-
contains: contains,
|
1141
|
-
matchWord: matchWord,
|
1142
|
-
createHashMap: createHashMap,
|
1143
|
-
createBetweenRule: createBetweenRule,
|
1144
|
-
createProceduralRule: createProceduralRule,
|
1145
|
-
getNextNonWsToken: function(tokens, index) { return getNextWhile(tokens, index, 1, function(token) { return token.name === "default"; }); },
|
1146
|
-
getPreviousNonWsToken: function(tokens, index) { return getNextWhile(tokens, index, -1, function(token) { return token.name === "default"; }); },
|
1147
|
-
getNextWhile: function(tokens, index, matcher) { return getNextWhile(tokens, index, 1, matcher); },
|
1148
|
-
getPreviousWhile: function(tokens, index, matcher) { return getNextWhile(tokens, index, -1, matcher); },
|
1149
|
-
whitespace: { token: "default", optional: true },
|
1150
|
-
getComputedStyle: getComputedStyle
|
1151
|
-
}
|
1152
|
-
};
|
1153
|
-
|
1154
|
-
//register the default language
|
1155
|
-
window.Sunlight.registerLanguage(DEFAULT_LANGUAGE, { punctuation: /(?!x)x/, numberParser: EMPTY });
|
1156
|
-
|
1157
|
-
}(this, document));
|