Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
O
osticket
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
docker
osticket
Commits
9b0c9fc0
Commit
9b0c9fc0
authored
11 years ago
by
Jared Hancock
Browse files
Options
Downloads
Patches
Plain Diff
Use PJAX to speed requests in the same panel
parent
6f9c14b2
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
include/staff/footer.inc.php
+11
-0
11 additions, 0 deletions
include/staff/footer.inc.php
include/staff/header.inc.php
+14
-7
14 additions, 7 deletions
include/staff/header.inc.php
js/jquery.pjax.js
+839
-0
839 additions, 0 deletions
js/jquery.pjax.js
scp/js/ticket.js
+4
-2
4 additions, 2 deletions
scp/js/ticket.js
with
868 additions
and
9 deletions
include/staff/footer.inc.php
+
11
−
0
View file @
9b0c9fc0
<?php
if
(
!
isset
(
$_SERVER
[
'HTTP_X_PJAX'
]))
{
?>
</div>
<div
id=
"footer"
>
Copyright
©
2006-
<?php
echo
date
(
'Y'
);
?>
<?php
echo
(
string
)
$ost
->
company
?:
'osTicket.com'
;
?>
All Rights Reserved.
...
...
@@ -20,5 +21,15 @@ if(is_object($thisstaff) && $thisstaff->isStaff()) { ?>
<div
class=
"dialog"
style=
"display:none;width:650px;"
id=
"popup"
>
<div
class=
"body"
></div>
</div>
<script
type=
"text/javascript"
>
if
(
$
.
support
.
pjax
)
{
$
(
document
).
on
(
'
click
'
,
'
a
'
,
function
(
event
)
{
if
(
!
$
(
this
).
hasClass
(
'
no-pjax
'
))
$
.
pjax
.
click
(
event
,
{
container
:
$
(
'
#content
'
)})
})
}
</script>
</body>
</html>
<?php
}
# endif X_PJAX ?>
This diff is collapsed.
Click to expand it.
include/staff/header.inc.php
+
14
−
7
View file @
9b0c9fc0
<?php
if
(
!
isset
(
$_SERVER
[
'HTTP_X_PJAX'
]))
{
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
...
...
@@ -13,6 +14,7 @@
<![endif]-->
<script
type=
"text/javascript"
src=
"
<?php
echo
ROOT_PATH
;
?>
js/jquery-1.8.3.min.js"
></script>
<script
type=
"text/javascript"
src=
"
<?php
echo
ROOT_PATH
;
?>
js/jquery-ui-1.10.3.custom.min.js"
></script>
<script
type=
"text/javascript"
src=
"
<?php
echo
ROOT_PATH
;
?>
js/jquery.pjax.js"
></script>
<script
type=
"text/javascript"
src=
"../js/jquery.multifile.js"
></script>
<script
type=
"text/javascript"
src=
"./js/tips.js"
></script>
<script
type=
"text/javascript"
src=
"
<?php
echo
ROOT_PATH
;
?>
js/redactor.min.js"
></script>
...
...
@@ -53,27 +55,31 @@
<p
id=
"info"
>
Welcome,
<strong>
<?php
echo
$thisstaff
->
getFirstName
();
?>
</strong>
<?php
if
(
$thisstaff
->
isAdmin
()
&&
!
defined
(
'ADMINPAGE'
))
{
?>
|
<a
href=
"admin.php"
>
Admin Panel
</a>
|
<a
href=
"admin.php"
class=
"no-pjax"
>
Admin Panel
</a>
<?php
}
else
{
?>
|
<a
href=
"index.php"
>
Staff Panel
</a>
|
<a
href=
"index.php"
class=
"no-pjax"
>
Staff Panel
</a>
<?php
}
?>
|
<a
href=
"profile.php"
>
My Preferences
</a>
|
<a
href=
"logout.php?auth=
<?php
echo
$ost
->
getLinkToken
();
?>
"
>
Log Out
</a>
|
<a
href=
"logout.php?auth=
<?php
echo
$ost
->
getLinkToken
();
?>
"
class=
"no-pjax"
>
Log Out
</a>
</p>
</div>
<ul
id=
"nav"
>
<?php
if
((
$tabs
=
$nav
->
getTabs
())
&&
is_array
(
$tabs
)){
foreach
(
$tabs
as
$name
=>
$tab
)
{
echo
sprintf
(
'<li class="%s"><a href="%s">%s</a>'
,
$tab
[
'active'
]
?
'active'
:
'inactive'
,
$tab
[
'href'
],
$tab
[
'desc'
]);
echo
sprintf
(
'<li class="%s"><a href="%s"
class="no-pjax"
>%s</a>'
,
$tab
[
'active'
]
?
'active'
:
'inactive'
,
$tab
[
'href'
],
$tab
[
'desc'
]);
if
(
!
$tab
[
'active'
]
&&
(
$subnav
=
$nav
->
getSubMenu
(
$name
))){
echo
"<ul>
\n
"
;
foreach
(
$subnav
as
$k
=>
$item
)
{
if
(
!
(
$id
=
$item
[
'id'
]))
$id
=
"nav
$k
"
;
echo
sprintf
(
'<li><a class="%s" href="%s" title="%s" id="%s">%s</a></li>'
,
$item
[
'iconclass'
],
$item
[
'href'
],
$item
[
'title'
],
$id
,
$item
[
'desc'
]);
echo
sprintf
(
'<li><a class="%s %s" href="%s" title="%s" id="%s">%s</a></li>'
,
$item
[
'iconclass'
],
$tab
[
'active'
]
?
''
:
'no-pjax'
,
$item
[
'href'
],
$item
[
'title'
],
$id
,
$item
[
'desc'
]);
}
echo
"
\n
</ul>
\n
"
;
}
...
...
@@ -107,7 +113,8 @@
}
?>
</ul>
<div
id=
"content"
>
<div
id=
"content"
data-pjax-container
>
<?php
}
# endif X_PJAX ?>
<?
php
if
(
$errors
[
'err'
])
{
?>
<div
id=
"msg_error"
>
<?php
echo
$errors
[
'err'
];
?>
</div>
<?php
}
elseif
(
$msg
)
{
?>
...
...
This diff is collapsed.
Click to expand it.
js/jquery.pjax.js
0 → 100644
+
839
−
0
View file @
9b0c9fc0
// jquery.pjax.js
// copyright chris wanstrath
// https://github.com/defunkt/jquery-pjax
(
function
(
$
){
// When called on a container with a selector, fetches the href with
// ajax into the container or with the data-pjax attribute on the link
// itself.
//
// Tries to make sure the back button and ctrl+click work the way
// you'd expect.
//
// Exported as $.fn.pjax
//
// Accepts a jQuery ajax options object that may include these
// pjax specific options:
//
//
// container - Where to stick the response body. Usually a String selector.
// $(container).html(xhr.responseBody)
// (default: current jquery context)
// push - Whether to pushState the URL. Defaults to true (of course).
// replace - Want to use replaceState instead? That's cool.
//
// For convenience the second parameter can be either the container or
// the options object.
//
// Returns the jQuery object
function
fnPjax
(
selector
,
container
,
options
)
{
var
context
=
this
return
this
.
on
(
'
click.pjax
'
,
selector
,
function
(
event
)
{
var
opts
=
$
.
extend
({},
optionsFor
(
container
,
options
))
if
(
!
opts
.
container
)
opts
.
container
=
$
(
this
).
attr
(
'
data-pjax
'
)
||
context
handleClick
(
event
,
opts
)
})
}
// Public: pjax on click handler
//
// Exported as $.pjax.click.
//
// event - "click" jQuery.Event
// options - pjax options
//
// Examples
//
// $(document).on('click', 'a', $.pjax.click)
// // is the same as
// $(document).pjax('a')
//
// $(document).on('click', 'a', function(event) {
// var container = $(this).closest('[data-pjax-container]')
// $.pjax.click(event, container)
// })
//
// Returns nothing.
function
handleClick
(
event
,
container
,
options
)
{
options
=
optionsFor
(
container
,
options
)
var
link
=
event
.
currentTarget
if
(
link
.
tagName
.
toUpperCase
()
!==
'
A
'
)
throw
"
$.fn.pjax or $.pjax.click requires an anchor element
"
// Middle click, cmd click, and ctrl click should open
// links in a new tab as normal.
if
(
event
.
which
>
1
||
event
.
metaKey
||
event
.
ctrlKey
||
event
.
shiftKey
||
event
.
altKey
)
return
// Ignore cross origin links
if
(
location
.
protocol
!==
link
.
protocol
||
location
.
hostname
!==
link
.
hostname
)
return
// Ignore anchors on the same page
if
(
link
.
hash
&&
link
.
href
.
replace
(
link
.
hash
,
''
)
===
location
.
href
.
replace
(
location
.
hash
,
''
))
return
// Ignore empty anchor "foo.html#"
if
(
link
.
href
===
location
.
href
+
'
#
'
)
return
var
defaults
=
{
url
:
link
.
href
,
container
:
$
(
link
).
attr
(
'
data-pjax
'
),
target
:
link
}
var
opts
=
$
.
extend
({},
defaults
,
options
)
var
clickEvent
=
$
.
Event
(
'
pjax:click
'
)
$
(
link
).
trigger
(
clickEvent
,
[
opts
])
if
(
!
clickEvent
.
isDefaultPrevented
())
{
pjax
(
opts
)
event
.
preventDefault
()
$
(
link
).
trigger
(
'
pjax:clicked
'
,
[
opts
])
}
}
// Public: pjax on form submit handler
//
// Exported as $.pjax.submit
//
// event - "click" jQuery.Event
// options - pjax options
//
// Examples
//
// $(document).on('submit', 'form', function(event) {
// var container = $(this).closest('[data-pjax-container]')
// $.pjax.submit(event, container)
// })
//
// Returns nothing.
function
handleSubmit
(
event
,
container
,
options
)
{
options
=
optionsFor
(
container
,
options
)
var
form
=
event
.
currentTarget
if
(
form
.
tagName
.
toUpperCase
()
!==
'
FORM
'
)
throw
"
$.pjax.submit requires a form element
"
var
defaults
=
{
type
:
form
.
method
.
toUpperCase
(),
url
:
form
.
action
,
data
:
$
(
form
).
serializeArray
(),
container
:
$
(
form
).
attr
(
'
data-pjax
'
),
target
:
form
}
pjax
(
$
.
extend
({},
defaults
,
options
))
event
.
preventDefault
()
}
// Loads a URL with ajax, puts the response body inside a container,
// then pushState()'s the loaded URL.
//
// Works just like $.ajax in that it accepts a jQuery ajax
// settings object (with keys like url, type, data, etc).
//
// Accepts these extra keys:
//
// container - Where to stick the response body.
// $(container).html(xhr.responseBody)
// push - Whether to pushState the URL. Defaults to true (of course).
// replace - Want to use replaceState instead? That's cool.
//
// Use it just like $.ajax:
//
// var xhr = $.pjax({ url: this.href, container: '#main' })
// console.log( xhr.readyState )
//
// Returns whatever $.ajax returns.
function
pjax
(
options
)
{
options
=
$
.
extend
(
true
,
{},
$
.
ajaxSettings
,
pjax
.
defaults
,
options
)
if
(
$
.
isFunction
(
options
.
url
))
{
options
.
url
=
options
.
url
()
}
var
target
=
options
.
target
var
hash
=
parseURL
(
options
.
url
).
hash
var
context
=
options
.
context
=
findContainerFor
(
options
.
container
)
// We want the browser to maintain two separate internal caches: one
// for pjax'd partial page loads and one for normal page loads.
// Without adding this secret parameter, some browsers will often
// confuse the two.
if
(
!
options
.
data
)
options
.
data
=
{}
options
.
data
.
_pjax
=
context
.
selector
function
fire
(
type
,
args
)
{
var
event
=
$
.
Event
(
type
,
{
relatedTarget
:
target
})
context
.
trigger
(
event
,
args
)
return
!
event
.
isDefaultPrevented
()
}
var
timeoutTimer
options
.
beforeSend
=
function
(
xhr
,
settings
)
{
// No timeout for non-GET requests
// Its not safe to request the resource again with a fallback method.
if
(
settings
.
type
!==
'
GET
'
)
{
settings
.
timeout
=
0
}
xhr
.
setRequestHeader
(
'
X-PJAX
'
,
'
true
'
)
xhr
.
setRequestHeader
(
'
X-PJAX-Container
'
,
context
.
selector
)
if
(
!
fire
(
'
pjax:beforeSend
'
,
[
xhr
,
settings
]))
return
false
if
(
settings
.
timeout
>
0
)
{
timeoutTimer
=
setTimeout
(
function
()
{
if
(
fire
(
'
pjax:timeout
'
,
[
xhr
,
options
]))
xhr
.
abort
(
'
timeout
'
)
},
settings
.
timeout
)
// Clear timeout setting so jquerys internal timeout isn't invoked
settings
.
timeout
=
0
}
options
.
requestUrl
=
parseURL
(
settings
.
url
).
href
}
options
.
complete
=
function
(
xhr
,
textStatus
)
{
if
(
timeoutTimer
)
clearTimeout
(
timeoutTimer
)
fire
(
'
pjax:complete
'
,
[
xhr
,
textStatus
,
options
])
fire
(
'
pjax:end
'
,
[
xhr
,
options
])
}
options
.
error
=
function
(
xhr
,
textStatus
,
errorThrown
)
{
var
container
=
extractContainer
(
""
,
xhr
,
options
)
var
allowed
=
fire
(
'
pjax:error
'
,
[
xhr
,
textStatus
,
errorThrown
,
options
])
if
(
options
.
type
==
'
GET
'
&&
textStatus
!==
'
abort
'
&&
allowed
)
{
locationReplace
(
container
.
url
)
}
}
options
.
success
=
function
(
data
,
status
,
xhr
)
{
// If $.pjax.defaults.version is a function, invoke it first.
// Otherwise it can be a static string.
var
currentVersion
=
(
typeof
$
.
pjax
.
defaults
.
version
===
'
function
'
)
?
$
.
pjax
.
defaults
.
version
()
:
$
.
pjax
.
defaults
.
version
var
latestVersion
=
xhr
.
getResponseHeader
(
'
X-PJAX-Version
'
)
var
container
=
extractContainer
(
data
,
xhr
,
options
)
// If there is a layout version mismatch, hard load the new url
if
(
currentVersion
&&
latestVersion
&&
currentVersion
!==
latestVersion
)
{
locationReplace
(
container
.
url
)
return
}
// If the new response is missing a body, hard load the page
if
(
!
container
.
contents
)
{
locationReplace
(
container
.
url
)
return
}
pjax
.
state
=
{
id
:
options
.
id
||
uniqueId
(),
url
:
container
.
url
,
title
:
container
.
title
,
container
:
context
.
selector
,
fragment
:
options
.
fragment
,
timeout
:
options
.
timeout
}
if
(
options
.
push
||
options
.
replace
)
{
window
.
history
.
replaceState
(
pjax
.
state
,
container
.
title
,
container
.
url
)
}
// Clear out any focused controls before inserting new page contents.
document
.
activeElement
.
blur
()
if
(
container
.
title
)
document
.
title
=
container
.
title
context
.
html
(
container
.
contents
)
// FF bug: Won't autofocus fields that are inserted via JS.
// This behavior is incorrect. So if theres no current focus, autofocus
// the last field.
//
// http://www.w3.org/html/wg/drafts/html/master/forms.html
var
autofocusEl
=
context
.
find
(
'
input[autofocus], textarea[autofocus]
'
).
last
()[
0
]
if
(
autofocusEl
&&
document
.
activeElement
!==
autofocusEl
)
{
autofocusEl
.
focus
();
}
executeScriptTags
(
container
.
scripts
)
// Scroll to top by default
if
(
typeof
options
.
scrollTo
===
'
number
'
)
$
(
window
).
scrollTop
(
options
.
scrollTo
)
// If the URL has a hash in it, make sure the browser
// knows to navigate to the hash.
if
(
hash
!==
''
)
{
// Avoid using simple hash set here. Will add another history
// entry. Replace the url with replaceState and scroll to target
// by hand.
//
// window.location.hash = hash
var
url
=
parseURL
(
container
.
url
)
url
.
hash
=
hash
pjax
.
state
.
url
=
url
.
href
window
.
history
.
replaceState
(
pjax
.
state
,
container
.
title
,
url
.
href
)
var
target
=
$
(
url
.
hash
)
if
(
target
.
length
)
$
(
window
).
scrollTop
(
target
.
offset
().
top
)
}
fire
(
'
pjax:success
'
,
[
data
,
status
,
xhr
,
options
])
}
// Initialize pjax.state for the initial page load. Assume we're
// using the container and options of the link we're loading for the
// back button to the initial page. This ensures good back button
// behavior.
if
(
!
pjax
.
state
)
{
pjax
.
state
=
{
id
:
uniqueId
(),
url
:
window
.
location
.
href
,
title
:
document
.
title
,
container
:
context
.
selector
,
fragment
:
options
.
fragment
,
timeout
:
options
.
timeout
}
window
.
history
.
replaceState
(
pjax
.
state
,
document
.
title
)
}
// Cancel the current request if we're already pjaxing
var
xhr
=
pjax
.
xhr
if
(
xhr
&&
xhr
.
readyState
<
4
)
{
xhr
.
onreadystatechange
=
$
.
noop
xhr
.
abort
()
}
pjax
.
options
=
options
var
xhr
=
pjax
.
xhr
=
$
.
ajax
(
options
)
if
(
xhr
.
readyState
>
0
)
{
if
(
options
.
push
&&
!
options
.
replace
)
{
// Cache current container element before replacing it
cachePush
(
pjax
.
state
.
id
,
context
.
clone
().
contents
())
window
.
history
.
pushState
(
null
,
""
,
stripPjaxParam
(
options
.
requestUrl
))
}
fire
(
'
pjax:start
'
,
[
xhr
,
options
])
fire
(
'
pjax:send
'
,
[
xhr
,
options
])
}
return
pjax
.
xhr
}
// Public: Reload current page with pjax.
//
// Returns whatever $.pjax returns.
function
pjaxReload
(
container
,
options
)
{
var
defaults
=
{
url
:
window
.
location
.
href
,
push
:
false
,
replace
:
true
,
scrollTo
:
false
}
return
pjax
(
$
.
extend
(
defaults
,
optionsFor
(
container
,
options
)))
}
// Internal: Hard replace current state with url.
//
// Work for around WebKit
// https://bugs.webkit.org/show_bug.cgi?id=93506
//
// Returns nothing.
function
locationReplace
(
url
)
{
window
.
history
.
replaceState
(
null
,
""
,
"
#
"
)
window
.
location
.
replace
(
url
)
}
var
initialPop
=
true
var
initialURL
=
window
.
location
.
href
var
initialState
=
window
.
history
.
state
// Initialize $.pjax.state if possible
// Happens when reloading a page and coming forward from a different
// session history.
if
(
initialState
&&
initialState
.
container
)
{
pjax
.
state
=
initialState
}
// Non-webkit browsers don't fire an initial popstate event
if
(
'
state
'
in
window
.
history
)
{
initialPop
=
false
}
// popstate handler takes care of the back and forward buttons
//
// You probably shouldn't use pjax on pages with other pushState
// stuff yet.
function
onPjaxPopstate
(
event
)
{
var
state
=
event
.
state
if
(
state
&&
state
.
container
)
{
// When coming forward from a separate history session, will get an
// initial pop with a state we are already at. Skip reloading the current
// page.
if
(
initialPop
&&
initialURL
==
state
.
url
)
return
// If popping back to the same state, just skip.
// Could be clicking back from hashchange rather than a pushState.
if
(
pjax
.
state
&&
pjax
.
state
.
id
===
state
.
id
)
return
var
container
=
$
(
state
.
container
)
if
(
container
.
length
)
{
var
direction
,
contents
=
cacheMapping
[
state
.
id
]
if
(
pjax
.
state
)
{
// Since state ids always increase, we can deduce the history
// direction from the previous state.
direction
=
pjax
.
state
.
id
<
state
.
id
?
'
forward
'
:
'
back
'
// Cache current container before replacement and inform the
// cache which direction the history shifted.
cachePop
(
direction
,
pjax
.
state
.
id
,
container
.
clone
().
contents
())
}
var
popstateEvent
=
$
.
Event
(
'
pjax:popstate
'
,
{
state
:
state
,
direction
:
direction
})
container
.
trigger
(
popstateEvent
)
var
options
=
{
id
:
state
.
id
,
url
:
state
.
url
,
container
:
container
,
push
:
false
,
fragment
:
state
.
fragment
,
timeout
:
state
.
timeout
,
scrollTo
:
false
}
if
(
contents
)
{
container
.
trigger
(
'
pjax:start
'
,
[
null
,
options
])
if
(
state
.
title
)
document
.
title
=
state
.
title
container
.
html
(
contents
)
pjax
.
state
=
state
container
.
trigger
(
'
pjax:end
'
,
[
null
,
options
])
}
else
{
pjax
(
options
)
}
// Force reflow/relayout before the browser tries to restore the
// scroll position.
container
[
0
].
offsetHeight
}
else
{
locationReplace
(
location
.
href
)
}
}
initialPop
=
false
}
// Fallback version of main pjax function for browsers that don't
// support pushState.
//
// Returns nothing since it retriggers a hard form submission.
function
fallbackPjax
(
options
)
{
var
url
=
$
.
isFunction
(
options
.
url
)
?
options
.
url
()
:
options
.
url
,
method
=
options
.
type
?
options
.
type
.
toUpperCase
()
:
'
GET
'
var
form
=
$
(
'
<form>
'
,
{
method
:
method
===
'
GET
'
?
'
GET
'
:
'
POST
'
,
action
:
url
,
style
:
'
display:none
'
})
if
(
method
!==
'
GET
'
&&
method
!==
'
POST
'
)
{
form
.
append
(
$
(
'
<input>
'
,
{
type
:
'
hidden
'
,
name
:
'
_method
'
,
value
:
method
.
toLowerCase
()
}))
}
var
data
=
options
.
data
if
(
typeof
data
===
'
string
'
)
{
$
.
each
(
data
.
split
(
'
&
'
),
function
(
index
,
value
)
{
var
pair
=
value
.
split
(
'
=
'
)
form
.
append
(
$
(
'
<input>
'
,
{
type
:
'
hidden
'
,
name
:
pair
[
0
],
value
:
pair
[
1
]}))
})
}
else
if
(
typeof
data
===
'
object
'
)
{
for
(
key
in
data
)
form
.
append
(
$
(
'
<input>
'
,
{
type
:
'
hidden
'
,
name
:
key
,
value
:
data
[
key
]}))
}
$
(
document
.
body
).
append
(
form
)
form
.
submit
()
}
// Internal: Generate unique id for state object.
//
// Use a timestamp instead of a counter since ids should still be
// unique across page loads.
//
// Returns Number.
function
uniqueId
()
{
return
(
new
Date
).
getTime
()
}
// Internal: Strips _pjax param from url
//
// url - String
//
// Returns String.
function
stripPjaxParam
(
url
)
{
return
url
.
replace
(
/
\?
_pjax=
[^
&
]
+&
?
/
,
'
?
'
)
.
replace
(
/_pjax=
[^
&
]
+&
?
/
,
''
)
.
replace
(
/
[\?
&
]
$/
,
''
)
}
// Internal: Parse URL components and returns a Locationish object.
//
// url - String URL
//
// Returns HTMLAnchorElement that acts like Location.
function
parseURL
(
url
)
{
var
a
=
document
.
createElement
(
'
a
'
)
a
.
href
=
url
return
a
}
// Internal: Build options Object for arguments.
//
// For convenience the first parameter can be either the container or
// the options object.
//
// Examples
//
// optionsFor('#container')
// // => {container: '#container'}
//
// optionsFor('#container', {push: true})
// // => {container: '#container', push: true}
//
// optionsFor({container: '#container', push: true})
// // => {container: '#container', push: true}
//
// Returns options Object.
function
optionsFor
(
container
,
options
)
{
// Both container and options
if
(
container
&&
options
)
options
.
container
=
container
// First argument is options Object
else
if
(
$
.
isPlainObject
(
container
)
)
options
=
container
// Only container
else
options
=
{
container
:
container
}
// Find and validate container
if
(
options
.
container
)
options
.
container
=
findContainerFor
(
options
.
container
)
return
options
}
// Internal: Find container element for a variety of inputs.
//
// Because we can't persist elements using the history API, we must be
// able to find a String selector that will consistently find the Element.
//
// container - A selector String, jQuery object, or DOM Element.
//
// Returns a jQuery object whose context is `document` and has a selector.
function
findContainerFor
(
container
)
{
container
=
$
(
container
)
if
(
!
container
.
length
)
{
throw
"
no pjax container for
"
+
container
.
selector
}
else
if
(
container
.
selector
!==
''
&&
container
.
context
===
document
)
{
return
container
}
else
if
(
container
.
attr
(
'
id
'
)
)
{
return
$
(
'
#
'
+
container
.
attr
(
'
id
'
))
}
else
{
throw
"
cant get selector for pjax container!
"
}
}
// Internal: Filter and find all elements matching the selector.
//
// Where $.fn.find only matches descendants, findAll will test all the
// top level elements in the jQuery object as well.
//
// elems - jQuery object of Elements
// selector - String selector to match
//
// Returns a jQuery object.
function
findAll
(
elems
,
selector
)
{
return
elems
.
filter
(
selector
).
add
(
elems
.
find
(
selector
));
}
function
parseHTML
(
html
)
{
return
$
.
parseHTML
(
html
,
document
,
true
)
}
// Internal: Extracts container and metadata from response.
//
// 1. Extracts X-PJAX-URL header if set
// 2. Extracts inline <title> tags
// 3. Builds response Element and extracts fragment if set
//
// data - String response data
// xhr - XHR response
// options - pjax options Object
//
// Returns an Object with url, title, and contents keys.
function
extractContainer
(
data
,
xhr
,
options
)
{
var
obj
=
{}
// Prefer X-PJAX-URL header if it was set, otherwise fallback to
// using the original requested url.
obj
.
url
=
stripPjaxParam
(
xhr
.
getResponseHeader
(
'
X-PJAX-URL
'
)
||
options
.
requestUrl
)
// Attempt to parse response html into elements
if
(
/<html/i
.
test
(
data
))
{
var
$head
=
$
(
parseHTML
(
data
.
match
(
/<head
[^
>
]
*>
([\s\S
.
]
*
)
<
\/
head>/i
)[
0
]))
var
$body
=
$
(
parseHTML
(
data
.
match
(
/<body
[^
>
]
*>
([\s\S
.
]
*
)
<
\/
body>/i
)[
0
]))
}
else
{
var
$head
=
$body
=
$
(
parseHTML
(
data
))
}
// If response data is empty, return fast
if
(
$body
.
length
===
0
)
return
obj
// If there's a <title> tag in the header, use it as
// the page's title.
obj
.
title
=
findAll
(
$head
,
'
title
'
).
last
().
text
()
if
(
options
.
fragment
)
{
// If they specified a fragment, look for it in the response
// and pull it out.
if
(
options
.
fragment
===
'
body
'
)
{
var
$fragment
=
$body
}
else
{
var
$fragment
=
findAll
(
$body
,
options
.
fragment
).
first
()
}
if
(
$fragment
.
length
)
{
obj
.
contents
=
$fragment
.
contents
()
// If there's no title, look for data-title and title attributes
// on the fragment
if
(
!
obj
.
title
)
obj
.
title
=
$fragment
.
attr
(
'
title
'
)
||
$fragment
.
data
(
'
title
'
)
}
}
else
if
(
!
/<html/i
.
test
(
data
))
{
obj
.
contents
=
$body
}
// Clean up any <title> tags
if
(
obj
.
contents
)
{
// Remove any parent title elements
obj
.
contents
=
obj
.
contents
.
not
(
function
()
{
return
$
(
this
).
is
(
'
title
'
)
})
// Then scrub any titles from their descendants
obj
.
contents
.
find
(
'
title
'
).
remove
()
// Gather all script[src] elements
obj
.
scripts
=
findAll
(
obj
.
contents
,
'
script[src]
'
).
remove
()
obj
.
contents
=
obj
.
contents
.
not
(
obj
.
scripts
)
}
// Trim any whitespace off the title
if
(
obj
.
title
)
obj
.
title
=
$
.
trim
(
obj
.
title
)
return
obj
}
// Load an execute scripts using standard script request.
//
// Avoids jQuery's traditional $.getScript which does a XHR request and
// globalEval.
//
// scripts - jQuery object of script Elements
//
// Returns nothing.
function
executeScriptTags
(
scripts
)
{
if
(
!
scripts
)
return
var
existingScripts
=
$
(
'
script[src]
'
)
scripts
.
each
(
function
()
{
var
src
=
this
.
src
var
matchedScripts
=
existingScripts
.
filter
(
function
()
{
return
this
.
src
===
src
})
if
(
matchedScripts
.
length
)
return
var
script
=
document
.
createElement
(
'
script
'
)
script
.
type
=
$
(
this
).
attr
(
'
type
'
)
script
.
src
=
$
(
this
).
attr
(
'
src
'
)
document
.
head
.
appendChild
(
script
)
})
}
// Internal: History DOM caching class.
var
cacheMapping
=
{}
var
cacheForwardStack
=
[]
var
cacheBackStack
=
[]
// Push previous state id and container contents into the history
// cache. Should be called in conjunction with `pushState` to save the
// previous container contents.
//
// id - State ID Number
// value - DOM Element to cache
//
// Returns nothing.
function
cachePush
(
id
,
value
)
{
cacheMapping
[
id
]
=
value
cacheBackStack
.
push
(
id
)
// Remove all entires in forward history stack after pushing
// a new page.
while
(
cacheForwardStack
.
length
)
delete
cacheMapping
[
cacheForwardStack
.
shift
()]
// Trim back history stack to max cache length.
while
(
cacheBackStack
.
length
>
pjax
.
defaults
.
maxCacheLength
)
delete
cacheMapping
[
cacheBackStack
.
shift
()]
}
// Shifts cache from directional history cache. Should be
// called on `popstate` with the previous state id and container
// contents.
//
// direction - "forward" or "back" String
// id - State ID Number
// value - DOM Element to cache
//
// Returns nothing.
function
cachePop
(
direction
,
id
,
value
)
{
var
pushStack
,
popStack
cacheMapping
[
id
]
=
value
if
(
direction
===
'
forward
'
)
{
pushStack
=
cacheBackStack
popStack
=
cacheForwardStack
}
else
{
pushStack
=
cacheForwardStack
popStack
=
cacheBackStack
}
pushStack
.
push
(
id
)
if
(
id
=
popStack
.
pop
())
delete
cacheMapping
[
id
]
}
// Public: Find version identifier for the initial page load.
//
// Returns String version or undefined.
function
findVersion
()
{
return
$
(
'
meta
'
).
filter
(
function
()
{
var
name
=
$
(
this
).
attr
(
'
http-equiv
'
)
return
name
&&
name
.
toUpperCase
()
===
'
X-PJAX-VERSION
'
}).
attr
(
'
content
'
)
}
// Install pjax functions on $.pjax to enable pushState behavior.
//
// Does nothing if already enabled.
//
// Examples
//
// $.pjax.enable()
//
// Returns nothing.
function
enable
()
{
$
.
fn
.
pjax
=
fnPjax
$
.
pjax
=
pjax
$
.
pjax
.
enable
=
$
.
noop
$
.
pjax
.
disable
=
disable
$
.
pjax
.
click
=
handleClick
$
.
pjax
.
submit
=
handleSubmit
$
.
pjax
.
reload
=
pjaxReload
$
.
pjax
.
defaults
=
{
timeout
:
650
,
push
:
true
,
replace
:
false
,
type
:
'
GET
'
,
dataType
:
'
html
'
,
scrollTo
:
0
,
maxCacheLength
:
20
,
version
:
findVersion
}
$
(
window
).
on
(
'
popstate.pjax
'
,
onPjaxPopstate
)
}
// Disable pushState behavior.
//
// This is the case when a browser doesn't support pushState. It is
// sometimes useful to disable pushState for debugging on a modern
// browser.
//
// Examples
//
// $.pjax.disable()
//
// Returns nothing.
function
disable
()
{
$
.
fn
.
pjax
=
function
()
{
return
this
}
$
.
pjax
=
fallbackPjax
$
.
pjax
.
enable
=
enable
$
.
pjax
.
disable
=
$
.
noop
$
.
pjax
.
click
=
$
.
noop
$
.
pjax
.
submit
=
$
.
noop
$
.
pjax
.
reload
=
function
()
{
window
.
location
.
reload
()
}
$
(
window
).
off
(
'
popstate.pjax
'
,
onPjaxPopstate
)
}
// Add the state property to jQuery's event object so we can use it in
// $(window).bind('popstate')
if
(
$
.
inArray
(
'
state
'
,
$
.
event
.
props
)
<
0
)
$
.
event
.
props
.
push
(
'
state
'
)
// Is pjax supported by this browser?
$
.
support
.
pjax
=
window
.
history
&&
window
.
history
.
pushState
&&
window
.
history
.
replaceState
&&
// pushState isn't reliable on iOS until 5.
!
navigator
.
userAgent
.
match
(
/
((
iPod|iPhone|iPad
)
.+
\b
OS
\s
+
[
1-4
]
|WebApps
\/
.+CFNetwork
)
/
)
$
.
support
.
pjax
?
enable
()
:
disable
()
})(
jQuery
);
This diff is collapsed.
Click to expand it.
scp/js/ticket.js
+
4
−
2
View file @
9b0c9fc0
...
...
@@ -265,7 +265,7 @@ $.autoLock = autoLock;
UI & form events
*/
jQuery
(
function
(
$
)
{
var
ticket_onload
=
function
(
$
)
{
$
(
'
#response_options form
'
).
hide
();
$
(
'
#ticket_notes
'
).
hide
();
if
(
location
.
hash
!=
""
&&
$
(
'
#response_options
'
+
location
.
hash
).
length
)
{
...
...
@@ -407,7 +407,9 @@ jQuery(function($) {
// TODO: Add a hover-button to show just one image
});
});
});
};
$
(
ticket_onload
);
$
(
document
).
on
(
'
pjax:success
'
,
function
()
{
ticket_onload
(
jQuery
);
});
showImagesInline
=
function
(
urls
,
thread_id
)
{
var
selector
=
(
thread_id
==
undefined
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment