Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F18921189
PathTypeahead.js
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Referenced Files
None
Subscribers
None
PathTypeahead.js
View Options
/**
* @requires javelin-install
* javelin-typeahead
* javelin-dom
* javelin-request
* javelin-typeahead-ondemand-source
* javelin-util
* @provides path-typeahead
* @javelin
*/
JX
.
install
(
'PathTypeahead'
,
{
construct
:
function
(
config
)
{
this
.
_repositorySelect
=
config
.
repo_select
;
this
.
_hardpoint
=
config
.
hardpoint
;
this
.
_input
=
config
.
path_input
;
this
.
_completeURI
=
config
.
completeURI
;
this
.
_validateURI
=
config
.
validateURI
;
this
.
_errorDisplay
=
config
.
error_display
;
/*
* Default values to preload the typeahead with, for extremely common
* cases.
*/
this
.
_textInputValues
=
config
.
repositoryDefaultPaths
;
this
.
_initializeDatasource
();
this
.
_initializeTypeahead
(
this
.
_input
);
},
members
:
{
/*
* DOM <select> elem for choosing the repository of a path.
*/
_repositorySelect
:
null
,
/*
* DOM parent div "hardpoint" to be passed to the JX.Typeahead.
*/
_hardpoint
:
null
,
/*
* DOM element to display errors.
*/
_errorDisplay
:
null
,
/*
* URI to query for typeahead results, to be passed to the
* TypeaheadOnDemandSource.
*/
_completeURI
:
null
,
/*
* Underlying JX.TypeaheadOnDemandSource instance
*/
_datasource
:
null
,
/*
* Underlying JX.Typeahead instance
*/
_typeahead
:
null
,
/*
* Underlying input
*/
_input
:
null
,
/*
* Whenever the user changes the typeahead value, we track the change
* here, keyed by the selected repository ID. That way, we can restore
* typed values if they change the repository choice and then change back.
*/
_textInputValues
:
null
,
/*
* Configurable endpoint for server-side path validation
*/
_validateURI
:
null
,
/*
* Keep the validation AJAX request so we don't send several.
*/
_validationInflight
:
null
,
/*
* Installs path-specific behaviors and then starts the underlying
* typeahead.
*/
start
:
function
()
{
if
(
this
.
_typeahead
.
getValue
())
{
this
.
_textInputValues
[
this
.
_repositorySelect
.
value
]
=
this
.
_typeahead
.
getValue
();
}
this
.
_typeahead
.
listen
(
'change'
,
JX
.
bind
(
this
,
function
(
value
)
{
this
.
_textInputValues
[
this
.
_repositorySelect
.
value
]
=
value
;
this
.
_validate
();
}));
this
.
_typeahead
.
listen
(
'choose'
,
JX
.
bind
(
this
,
function
()
{
setTimeout
(
JX
.
bind
(
this
.
_typeahead
,
this
.
_typeahead
.
refresh
),
0
);
}));
var
repo_set_input
=
JX
.
bind
(
this
,
this
.
_onrepochange
);
this
.
_typeahead
.
listen
(
'start'
,
repo_set_input
);
JX
.
DOM
.
listen
(
this
.
_repositorySelect
,
'change'
,
null
,
repo_set_input
);
this
.
_typeahead
.
start
();
this
.
_validate
();
},
_onrepochange
:
function
()
{
this
.
_setPathInputBasedOnRepository
(
this
.
_typeahead
,
this
.
_textInputValues
);
this
.
_datasource
.
setAuxiliaryData
(
{
repositoryPHID
:
this
.
_repositorySelect
.
value
}
);
},
_setPathInputBasedOnRepository
:
function
(
typeahead
,
lookup
)
{
if
(
lookup
[
this
.
_repositorySelect
.
value
])
{
typeahead
.
setValue
(
lookup
[
this
.
_repositorySelect
.
value
]);
}
else
{
typeahead
.
setValue
(
'/'
);
}
},
_initializeDatasource
:
function
()
{
this
.
_datasource
=
new
JX
.
TypeaheadOnDemandSource
(
this
.
_completeURI
);
this
.
_datasource
.
setNormalizer
(
this
.
_datasourceNormalizer
);
this
.
_datasource
.
setQueryDelay
(
40
);
},
/*
* Construct and initialize the Typeahead.
* Must be called after initializing the datasource.
*/
_initializeTypeahead
:
function
(
path_input
)
{
this
.
_typeahead
=
new
JX
.
Typeahead
(
this
.
_hardpoint
,
path_input
);
this
.
_datasource
.
setMaximumResultCount
(
15
);
this
.
_typeahead
.
setDatasource
(
this
.
_datasource
);
},
_datasourceNormalizer
:
function
(
str
)
{
return
(
''
+
str
).
replace
(
/[\/]+/g
,
'\/'
);
},
_validate
:
function
()
{
var
input
=
this
.
_input
;
var
repo_id
=
this
.
_repositorySelect
.
value
;
var
input_value
=
input
.
value
;
var
error_display
=
this
.
_errorDisplay
;
if
(
!
input_value
.
length
)
{
input
.
value
=
'/'
;
input_value
=
'/'
;
}
if
(
this
.
_validationInflight
)
{
this
.
_validationInflight
.
abort
();
this
.
_validationInflight
=
null
;
}
var
validation_request
=
new
JX
.
Request
(
this
.
_validateURI
,
function
(
payload
)
{
// Don't change validation display state if the input has been
// changed since we started validation
if
(
input
.
value
===
input_value
)
{
if
(
payload
.
valid
)
{
JX
.
DOM
.
alterClass
(
error_display
,
'invalid'
,
false
);
JX
.
DOM
.
alterClass
(
error_display
,
'valid'
,
true
);
}
else
{
JX
.
DOM
.
alterClass
(
error_display
,
'invalid'
,
true
);
JX
.
DOM
.
alterClass
(
error_display
,
'valid'
,
false
);
}
JX
.
DOM
.
setContent
(
error_display
,
payload
.
message
);
}
});
validation_request
.
listen
(
'finally'
,
function
()
{
JX
.
DOM
.
alterClass
(
error_display
,
'validating'
,
false
);
this
.
_validationInflight
=
null
;
});
validation_request
.
setData
(
{
repositoryPHID
:
repo_id
,
path
:
input_value
});
this
.
_validationInflight
=
validation_request
;
validation_request
.
setTimeout
(
750
);
validation_request
.
send
();
}
}
});
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 11, 1:51 PM (1 d, 17 h)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
8264970
Default Alt Text
PathTypeahead.js (5 KB)
Attached To
Mode
rP Phabricator
Attached
Detach File
Event Timeline
Log In to Comment