44 Commits
Author SHA1 Message Date
Andrey Savchenko 357753f84b Updated changelog and version for 1.3.2 2015-08-27 14:06:08 +03:00
Andrey Savchenko 9d1dddb462 Normalized slashing on adding files to release zip file. 2015-08-27 14:05:48 +03:00
Andrey Savchenko d88a566aee Fixed dynamic method call to prevent crash on PHP 7. 2015-08-27 14:05:19 +03:00
Andrey Savchenko b976b26454 Updated version in header 2015-08-15 21:06:35 +03:00
Andrey Savchenko a00b11f78a Updated changelog for 1.3.1 2015-08-12 00:15:24 +03:00
Andrey Savchenko 32f300af7f Added check to catch event stops without matching starts
Fixes #7
2015-08-12 00:14:33 +03:00
Andrey Savchenko a3572063d2 Updated changelog and version 2015-06-12 22:06:33 +03:00
Andrey Savchenko e8f8e9a4b6 Implemented release command in robo 2015-06-12 21:06:07 +03:00
Andrey Savchenko cf44efbe64 Added version getter to robo file 2015-06-12 21:05:50 +03:00
Andrey Savchenko 2289923666 Updated main file for code style 2015-06-12 21:05:24 +03:00
Andrey Savchenko b82cd35cf8 Updated gitignore 2015-06-12 20:58:52 +03:00
Andrey Savchenko 8e441c935f Added task to set plugin version 2015-06-11 17:23:31 +03:00
Andrey Savchenko 7dfea751f5 Made method calls more compact 2015-06-11 12:40:19 +03:00
Andrey Savchenko a3cc36b661 Removed commented out debug code 2015-06-11 12:40:07 +03:00
Andrey Savchenko 47caf94cfe Another end of file new line 2015-06-11 12:33:45 +03:00
Andrey Savchenko d8298b1700 Made comparisons strict 2015-06-11 12:27:28 +03:00
Andrey Savchenko 5072bbbaad Added new lines to end of files for code style 2015-06-11 12:26:27 +03:00
Andrey Savchenko b32d60dfce Updated Stopwatch dependency 2015-06-11 12:26:00 +03:00
Andrey Savchenko c593e1e925 Tightened condition on Hybrid events to prevent breakage with v3
Fixes #4
2015-06-11 11:56:02 +03:00
Andrey Savchenko 112c14fde3 Added events class for Yoast plugins 2015-04-06 10:19:57 +03:00
Andrey Savchenko df40e389ad Precompiled Mustache template 2015-04-06 09:46:09 +03:00
Andrey Savchenko fb7b2f025a Added Robo task for precompiling Mustache cache 2015-04-06 09:45:44 +03:00
Andrey Savchenko b87ce58f4a Implemented class for loading precompiled Mustache cache 2015-04-06 09:45:12 +03:00
Andrey Savchenko 424fb74b29 Updated dependencies 2015-04-06 09:44:18 +03:00
Andrey Savchenko 5ed687499f Recompiled assets after dependencies update 2015-03-28 23:36:08 +02:00
Andrey Savchenko 1db8318edb Updated dependencies 2015-03-28 23:35:05 +02:00
Andrey Savchenko edb804d35f Update README.md
Added link to releases section for archive download.
2015-02-06 23:20:32 +01:00
Andrey Savchenko ce265e6dd2 Updated array keys for coding style. 2015-01-03 21:24:58 +02:00
Andrey Savchenko f3438de84b Implemented minified assets in queue. 2015-01-03 21:06:32 +02:00
Andrey Savchenko d0d70fddaf Recompiled assets. 2015-01-03 21:06:11 +02:00
Andrey Savchenko 48424c2b4c Updated RoboFile for less sourcemap and minified assets. 2015-01-03 21:05:40 +02:00
Andrey Savchenko b3be169798 Updated dependencies. 2015-01-03 20:49:14 +02:00
Andrey Savchenko 5a33c9329b Split plugins load into file load and following hook. 2014-11-07 20:55:37 +02:00
Andrey Savchenko 6fda82d443 Recompiled assets after Bootstrap update. 2014-10-30 17:34:15 +02:00
Andrey Savchenko c912f263a2 Updated Bootstrap dependency to 3.3.0 2014-10-30 17:32:56 +02:00
Andrey Savchenko 6c75879465 Adjusted command name in RoboFile to make what, not what from. 2014-10-24 15:42:22 +03:00
Andrey Savchenko db87114e3f Elaborated on Composer code use in license section. 2014-10-24 15:10:12 +03:00
Andrey Savchenko 6c7b6d6195 Added links to themes and docs. 2014-10-24 15:09:47 +03:00
Andrey Savchenko 40fd25490b Moved screenshot up for eye candy. 2014-10-24 15:09:22 +03:00
Andrey Savchenko f2f3c4f474 Updated dependencies. 2014-10-23 22:38:26 +03:00
Andrey Savchenko 59bc49bd56 Updated readme and moved changelog to separate file. 2014-10-23 22:15:24 +03:00
Andrey Savchenko 234ed808aa Recompiled JS and updated for new script name. 2014-10-23 22:11:53 +03:00
Andrey Savchenko b5161c2955 Updated compilation and watch commands in RoboFile. 2014-10-23 22:11:06 +03:00
Andrey Savchenko 4cdf206de9 Moved JS from inline PHP to own source file. 2014-10-23 22:09:48 +03:00
18 changed files with 676 additions and 199 deletions

No files matched your search

+2 -1
View File
@@ -1 +1,2 @@
vendor /vendor
/release
+39
View File
@@ -0,0 +1,39 @@
# Changelog
## 1.3.2
- fixed dynamic method call crash on PHP 7
- fixed issue with slashes in generated release archives
## 1.3.1
- fixed crash on event stop without matching start
## 1.3
- implemented minified assets
- implemented pre-cached template
- fixed crash with upcoming Hybrid Core v3
- implemented release build command
- split plugins_loaded hook into separate event
- added WP SEO event
## 1.2.1
- disabled tooltip animation to fix JS errors and UI disappearing from under cursor
## 1.2
- merged RP with additional core events in admin
- implemented (ballpark) toolbar event
- fixed issue with event offsets in timelines
## 1.1
- added SQL timeline
- added HTTP timeline
- switched tooltips implementation to Bootstrap script
## 1.0
- Initial public release
+13 -35
View File
@@ -1,4 +1,6 @@
# Laps — light WP profiler # Laps — light WordPress profiler
![Laps screenshot](http://i.imgur.com/zFokmkU.png)
Laps is light WordPress profiler (in a plugin), which aims to be: Laps is light WordPress profiler (in a plugin), which aims to be:
@@ -16,53 +18,29 @@ Out of the box Laps supports common stage of WordPress page life cycle:
And some of third party hooks conventions for themes using: And some of third party hooks conventions for themes using:
- Theme Hook Alliance - [Theme Hook Alliance](http://zamoose.github.io/themehookalliance/)
- Hybrid - [Hybrid](http://themehybrid.com/)
- Genesis - [Genesis](http://my.studiopress.com/themes/genesis/)
- Thematic - [Thematic](http://thematictheme.com/)
There are also additional optional timelines, displaying: There are also additional optional timelines, displaying:
- SQL queries (with `SAVEQUERIES` constant enabled) - SQL queries (with [`SAVEQUERIES` constant](http://codex.wordpress.org/Editing_wp-config.php#Save_queries_for_analysis) enabled)
- HTTP requests performed - HTTP requests performed
# Screenshot ## Installation
![Laps screenshot](http://i.imgur.com/zFokmkU.png) Download plugin archive from [releases section](https://github.com/Rarst/laps/releases).
# Installation Or install in plugin directory via [Composer](https://getcomposer.org/):
Laps is a Composer package and can be installed in plugin directory via:
composer create-project rarst/laps --no-dev composer create-project rarst/laps --no-dev
# Changelog ## License Info
## 1.2.1
- disabled tooltip animation to fix JS errors and UI disappearing from under cursor
## 1.2
- merged RP with additional core events in admin
- implemented (ballpark) toolbar event
- fixed issue with event offsets in timelines
## 1.1
- added SQL timeline
- added HTTP timeline
- switched tooltips implementation to Bootstrap script
## 1.0
- Initial public release
# License Info
Laps own code is licensed under MIT and it makes use of code from: Laps own code is licensed under MIT and it makes use of code from:
- Composer (MIT) - Composer Installers (MIT)
- Symfony Stopwatch (MIT) - Symfony Stopwatch (MIT)
- Mustache.php (MIT) - Mustache.php (MIT)
- Twitter Bootstrap (MIT) - Twitter Bootstrap (MIT)
+127 -19
View File
@@ -1,5 +1,7 @@
<?php <?php
require __DIR__ . '/vendor/autoload.php';
/** /**
* This is project's console commands configuration for Robo task runner. * This is project's console commands configuration for Robo task runner.
* *
@@ -12,40 +14,146 @@ class RoboFile extends \Robo\Tasks {
*/ */
public function watch() { public function watch() {
$less_callback = function () {
$this->less();
};
$this->taskWatch() $this->taskWatch()
->monitor( 'css/variables.less', $less_callback ) ->monitor( [ 'css/variables.less', 'css/laps.less' ], function () {
->monitor( 'css/laps.less', $less_callback ) $this->makeCss();
} )
->monitor( 'js/source.js', function () {
$this->makeJs();
} )
->run(); ->run();
} }
/** /**
* Compiles stylesheet from less into css. * Compiles all assets.
*/ */
public function less() { public function makeAll() {
$this->taskExec( 'lessc css/laps.less css/laps.css' )->run(); $this->makeCss();
$this->makeJs();
$this->makeMustache();
} }
/** /**
* Copies tooltip.js from Bootstrap sources and edits plugin name. * Compiles plugin's css file from less.
*/ */
public function tooltip() { public function makeCss() {
$replacements = array( $this->taskExec( 'lessc css/laps.less css/laps.css --source-map=css/laps.css.map' )->run();
'+function ($) {' => '// modified to use lapstooltip as plugin name' . "\n\n" . '+function ($) {',
'this.init(\'tooltip\'' => 'this.init(\'lapstooltip\'', $this->taskMinify( 'css/laps.css' )
'bs.tooltip' => 'bs.lapstooltip', ->run();
'$.fn.tooltip' => '$.fn.lapstooltip', }
/**
* Creates plugin's script file.
*/
public function makeJs() {
$this->taskConcat( [
'vendor/twbs/bootstrap/js/tooltip.js',
'js/source.js',
] )
->to( 'js/laps.js' )
->run();
$this->taskMinify( 'js/laps.js' )
->run();
}
/**
* Compiles plugin's mustache template
*/
public function makeMustache() {
$dir = __DIR__ . '/views/cache';
$this->_cleanDir( $dir );
$mustache = new \Mustache_Engine(
array(
'loader' => new \Mustache_Loader_FilesystemLoader( __DIR__ . '/views' ),
'cache' => $dir,
)
); );
$mustache->loadTemplate( 'laps' );
}
$source = strtr( file_get_contents( 'vendor/twbs/bootstrap/js/tooltip.js' ), $replacements ); /**
* @return string
*/
private function versionGet() {
$this->taskWriteToFile( 'js/tooltip.js' ) $content = file_get_contents( __DIR__ . '/laps.php' );
->text( $source )
if ( false !== preg_match( '|^Version: (?P<version>.+)$|m', $content, $matches ) ) {
return trim( $matches['version'] );
}
return '';
}
/**
* Sets the plugin version in header.
*
* @param string $version Version string.
*/
public function versionSet( $version ) {
$this->taskReplaceInFile( 'laps.php' )
->regex( '|^Version:.*$|m' )
->to( 'Version: ' . $version )
->run(); ->run();
} }
/**
* Creates release zip
*
* @param string $version
*/
public function makeRelease( $version = '' ) {
if ( empty( $version ) ) {
$version = $this->versionGet();
}
$this->taskFileSystemStack()
->mkdir( 'release' )
->run();
$this->taskCleanDir( 'release' )->run();
$this->taskExec( 'composer' )
->dir( __DIR__ . '/release' )
->arg( 'create-project rarst/laps laps ' . $version )
->arg( '--prefer-dist --no-dev' )
->run();
$this->taskExec( 'composer' )
->dir( __DIR__ . '/release/laps' )
->arg( 'dump-autoload --optimize' )
->run();
$zipFile = "release/laps-{$version}.zip";
$zipArchive = new ZipArchive();
if ( ! $zipArchive->open( $zipFile, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE ) ) {
die( "Failed to create archive\n" );
}
$finder = new Symfony\Component\Finder\Finder();
$finder->files()->in( 'release/laps' )->ignoreDotFiles( false );
/** @var \Symfony\Component\Finder\SplFileInfo $file */
foreach ( $finder as $file ) {
$relativePathname = str_replace( '\\', '/', $file->getRelativePathname() );
$zipArchive->addFile( $file->getRealPath(), 'laps/' . $relativePathname );
}
if ( ! $zipArchive->status === ZIPARCHIVE::ER_OK ) {
echo "Failed to write files to zip\n";
}
$zipArchive->close();
$this->taskDeleteDir( 'release/laps' )->run();
}
} }
Generated
+43 -34
View File
@@ -1,23 +1,23 @@
{ {
"_readme": [ "_readme": [
"This file locks the dependencies of your project to a known state", "This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"hash": "7495421e8df337988c9906e05aab637b", "hash": "7495421e8df337988c9906e05aab637b",
"packages": [ "packages": [
{ {
"name": "composer/installers", "name": "composer/installers",
"version": "v1.0.15", "version": "v1.0.21",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/composer/installers.git", "url": "https://github.com/composer/installers.git",
"reference": "8e6a72a78f6cfd537fde3350720dfdc9ae3c5621" "reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/composer/installers/zipball/8e6a72a78f6cfd537fde3350720dfdc9ae3c5621", "url": "https://api.github.com/repos/composer/installers/zipball/d64e23fce42a4063d63262b19b8e7c0f3b5e4c45",
"reference": "8e6a72a78f6cfd537fde3350720dfdc9ae3c5621", "reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45",
"shasum": "" "shasum": ""
}, },
"replace": { "replace": {
@@ -48,8 +48,7 @@
{ {
"name": "Kyle Robinson Young", "name": "Kyle Robinson Young",
"email": "kyle@dontkry.com", "email": "kyle@dontkry.com",
"homepage": "https://github.com/shama", "homepage": "https://github.com/shama"
"role": "Developer"
} }
], ],
"description": "A multi-framework Composer library installer", "description": "A multi-framework Composer library installer",
@@ -60,17 +59,23 @@
"Hurad", "Hurad",
"MODX Evo", "MODX Evo",
"OXID", "OXID",
"SMF",
"Thelia",
"WolfCMS", "WolfCMS",
"agl", "agl",
"aimeos",
"annotatecms", "annotatecms",
"bitrix", "bitrix",
"cakephp", "cakephp",
"chef",
"codeigniter", "codeigniter",
"concrete5", "concrete5",
"croogo", "croogo",
"dokuwiki",
"drupal", "drupal",
"elgg", "elgg",
"fuelphp", "fuelphp",
"grav",
"installer", "installer",
"joomla", "joomla",
"kohana", "kohana",
@@ -84,6 +89,7 @@
"phpbb", "phpbb",
"piwik", "piwik",
"ppi", "ppi",
"puppet",
"roundcube", "roundcube",
"shopware", "shopware",
"silverstripe", "silverstripe",
@@ -93,27 +99,28 @@
"zend", "zend",
"zikula" "zikula"
], ],
"time": "2014-06-23 16:25:28" "time": "2015-02-18 17:17:01"
}, },
{ {
"name": "mustache/mustache", "name": "mustache/mustache",
"version": "v2.6.1", "version": "v2.8.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/bobthecow/mustache.php.git", "url": "https://github.com/bobthecow/mustache.php.git",
"reference": "1430ca884912eaba2b3830856b45685733b16789" "reference": "64c28cc73e01d5edcef7de8cb2b16782615f648a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/1430ca884912eaba2b3830856b45685733b16789", "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/64c28cc73e01d5edcef7de8cb2b16782615f648a",
"reference": "1430ca884912eaba2b3830856b45685733b16789", "reference": "64c28cc73e01d5edcef7de8cb2b16782615f648a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.2.4" "php": ">=5.2.4"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "*" "fabpot/php-cs-fixer": "~1.6",
"phpunit/phpunit": "~3.7|~4.0"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@@ -138,34 +145,36 @@
"mustache", "mustache",
"templating" "templating"
], ],
"time": "2014-06-20 19:34:49" "time": "2015-04-01 06:37:33"
}, },
{ {
"name": "symfony/stopwatch", "name": "symfony/stopwatch",
"version": "v2.5.0", "version": "v2.7.0",
"target-dir": "Symfony/Component/Stopwatch",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/Stopwatch.git", "url": "https://github.com/symfony/Stopwatch.git",
"reference": "724d73604ebe6c1c9bdf36533b556123bd9075a1" "reference": "7702945bceddc0e1f744519abb8a2baeb94bd5ce"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/Stopwatch/zipball/724d73604ebe6c1c9bdf36533b556123bd9075a1", "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/7702945bceddc0e1f744519abb8a2baeb94bd5ce",
"reference": "724d73604ebe6c1c9bdf36533b556123bd9075a1", "reference": "7702945bceddc0e1f744519abb8a2baeb94bd5ce",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.3.3" "php": ">=5.3.9"
},
"require-dev": {
"symfony/phpunit-bridge": "~2.7"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.5-dev" "dev-master": "2.7-dev"
} }
}, },
"autoload": { "autoload": {
"psr-0": { "psr-4": {
"Symfony\\Component\\Stopwatch\\": "" "Symfony\\Component\\Stopwatch\\": ""
} }
}, },
@@ -176,33 +185,31 @@
"authors": [ "authors": [
{ {
"name": "Fabien Potencier", "name": "Fabien Potencier",
"email": "fabien@symfony.com", "email": "fabien@symfony.com"
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
}, },
{ {
"name": "Symfony Community", "name": "Symfony Community",
"homepage": "http://symfony.com/contributors" "homepage": "https://symfony.com/contributors"
} }
], ],
"description": "Symfony Stopwatch Component", "description": "Symfony Stopwatch Component",
"homepage": "http://symfony.com", "homepage": "https://symfony.com",
"time": "2014-04-18 20:40:13" "time": "2015-05-02 15:21:08"
} }
], ],
"packages-dev": [ "packages-dev": [
{ {
"name": "twbs/bootstrap", "name": "twbs/bootstrap",
"version": "v3.2.0", "version": "v3.3.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/twbs/bootstrap.git", "url": "https://github.com/twbs/bootstrap.git",
"reference": "c068162161154a4b85110ea1e7dd3d7897ce2b72" "reference": "a10eb60bc0b07b747fa0c4ebd8821eb7307bd07f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/twbs/bootstrap/zipball/c068162161154a4b85110ea1e7dd3d7897ce2b72", "url": "https://api.github.com/repos/twbs/bootstrap/zipball/a10eb60bc0b07b747fa0c4ebd8821eb7307bd07f",
"reference": "c068162161154a4b85110ea1e7dd3d7897ce2b72", "reference": "a10eb60bc0b07b747fa0c4ebd8821eb7307bd07f",
"shasum": "" "shasum": ""
}, },
"replace": { "replace": {
@@ -211,7 +218,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "3.2.x-dev" "dev-master": "3.3.x-dev"
} }
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
@@ -240,12 +247,14 @@
"responsive", "responsive",
"web" "web"
], ],
"time": "2014-06-26 16:36:48" "time": "2015-03-16 15:44:41"
} }
], ],
"aliases": [], "aliases": [],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": [], "stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [], "platform": [],
"platform-dev": [] "platform-dev": []
} }
+11 -16
View File
@@ -45,17 +45,6 @@
border-left: 1px solid #f5f5f5; border-left: 1px solid #f5f5f5;
min-width: 2px; min-width: 2px;
} }
#wpadminbar .laps-timeline .event[aria-valuenow="1"],
#wpadminbar .laps-timeline .event[aria-valuenow="2"] {
min-width: 30px;
}
#wpadminbar .laps-timeline .event[aria-valuenow="0"] {
color: #777777;
min-width: 30px;
background-color: transparent;
background-image: none;
box-shadow: none;
}
#wpadminbar .laps-timeline .event-theme { #wpadminbar .laps-timeline .event-theme {
background-color: #5cb85c; background-color: #5cb85c;
} }
@@ -75,8 +64,9 @@
position: absolute; position: absolute;
z-index: 100000; z-index: 100000;
display: block; display: block;
visibility: visible; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 12px; font-size: 12px;
font-weight: normal;
line-height: 1.4; line-height: 1.4;
opacity: 0; opacity: 0;
filter: alpha(opacity=0); filter: alpha(opacity=0);
@@ -126,13 +116,15 @@
} }
#wpadminbar .tooltip.top-left .tooltip-arrow { #wpadminbar .tooltip.top-left .tooltip-arrow {
bottom: 0; bottom: 0;
left: 5px; right: 5px;
margin-bottom: -5px;
border-width: 5px 5px 0; border-width: 5px 5px 0;
border-top-color: #464646; border-top-color: #464646;
} }
#wpadminbar .tooltip.top-right .tooltip-arrow { #wpadminbar .tooltip.top-right .tooltip-arrow {
bottom: 0; bottom: 0;
right: 5px; left: 5px;
margin-bottom: -5px;
border-width: 5px 5px 0; border-width: 5px 5px 0;
border-top-color: #464646; border-top-color: #464646;
} }
@@ -159,13 +151,15 @@
} }
#wpadminbar .tooltip.bottom-left .tooltip-arrow { #wpadminbar .tooltip.bottom-left .tooltip-arrow {
top: 0; top: 0;
left: 5px; right: 5px;
margin-top: -5px;
border-width: 0 5px 5px; border-width: 0 5px 5px;
border-bottom-color: #464646; border-bottom-color: #464646;
} }
#wpadminbar .tooltip.bottom-right .tooltip-arrow { #wpadminbar .tooltip.bottom-right .tooltip-arrow {
top: 0; top: 0;
right: 5px; left: 5px;
margin-top: -5px;
border-width: 0 5px 5px; border-width: 0 5px 5px;
border-bottom-color: #464646; border-bottom-color: #464646;
} }
@@ -177,3 +171,4 @@
line-height: 20px; line-height: 20px;
text-align: left; text-align: left;
} }
/*# sourceMappingURL=laps.css.map */
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["laps.less","C:/server/www/dev/wp-content/plugins/laps/vendor/twbs/bootstrap/less/progress-bars.less","C:/server/www/dev/wp-content/plugins/laps/vendor/twbs/bootstrap/less/mixins/vendor-prefixes.less","C:/server/www/dev/wp-content/plugins/laps/vendor/twbs/bootstrap/less/tooltip.less","C:/server/www/dev/wp-content/plugins/laps/vendor/twbs/bootstrap/less/variables.less","C:/server/www/dev/wp-content/plugins/laps/vendor/twbs/bootstrap/less/mixins/opacity.less"],"names":[],"mappings":"AAKA,WAEC,mBAEC;EACC,cAAA;EACA,UAAA;EACA,eAAA;EACA,QAAA;;AARH,WAEC,mBASC;EACC,UAAA;;AAZH,WAgBC;EAEC,eAAA;;AAEA,WAJD,0BAIE;EACA,6BAAA;;AArBH,WAgBC,0BAQC;EACC,aAAA;;AAzBH,WA6BC;ECRC,gBAAA;EACA,YAAA;EACA,mBAAA;EACA,yBAAA;EACA,kBAAA;ECsCA,sDAAA;EACQ,8CAAA;EFjCR,aAAA;EACA,kBAAA;;AAhCF,WA6BC,eAKC;ECHA,WAAA;EACA,SAAA;EACA,YAAA;EACA,eAAA;EACA,iBAAA;EACA,cAAA;EACA,kBAAA;EACA,yBAAA;ECyBA,sDAAA;EACQ,8CAAA;EAyHR,mCAAA;EACK,8BAAA;EACG,2BAAA;EFvJP,kBAAA;EACA,8BAAA;EACA,cAAA;;AAtCH,WA6BC,eAYC;EACC,yBAAA;;AA1CH,WA6BC,eAeC;EACC,yBAAA;;AA7CH,WA6BC,eAkBC;EACC,yBAAA;;AAhDH,WA6BC,eAqBC;EACC,yBAAA;;AAnDH,WA6BC,eAwBC;EACC,yBAAA;;AAtDH,WGCA;EACE,kBAAA;EACA,eAAA;EACA,cAAA;EAEA,aCiCwB,8CDjCxB;EACA,eAAA;EACA,mBAAA;EACA,gBAAA;EEXA,UAAA;EAGA,wBAAA;;AFWA,WAXF,SAWG;EEdD,YAAA;EAGA,yBAAA;;AFYA,WAZF,SAYG;EAAU,gBAAA;EAAmB,cAAA;;AAC9B,WAbF,SAaG;EAAU,gBAAA;EAAmB,cAAA;;AAC9B,WAdF,SAcG;EAAU,eAAA;EAAmB,cAAA;;AAC9B,WAfF,SAeG;EAAU,iBAAA;EAAmB,cAAA;;AHhBhC,WGoBA;EACE,gBAAA;EACA,gBAAA;EACA,cAAA;EACA,kBAAA;EACA,qBAAA;EACA,yBAAA;EACA,kBAAA;;AH3BF,WG+BA;EACE,kBAAA;EACA,QAAA;EACA,SAAA;EACA,yBAAA;EACA,mBAAA;;AAIA,WADF,SACG,IAAK;EACJ,SAAA;EACA,SAAA;EACA,iBAAA;EACA,uBAAA;EACA,yBAAA;;AAEF,WARF,SAQG,SAAU;EACT,SAAA;EACA,UAAA;EACA,mBAAA;EACA,uBAAA;EACA,yBAAA;;AAEF,WAfF,SAeG,UAAW;EACV,SAAA;EACA,SAAA;EACA,mBAAA;EACA,uBAAA;EACA,yBAAA;;AAEF,WAtBF,SAsBG,MAAO;EACN,QAAA;EACA,OAAA;EACA,gBAAA;EACA,2BAAA;EACA,2BAAA;;AAEF,WA7BF,SA6BG,KAAM;EACL,QAAA;EACA,QAAA;EACA,gBAAA;EACA,2BAAA;EACA,0BAAA;;AAEF,WApCF,SAoCG,OAAQ;EACP,MAAA;EACA,SAAA;EACA,iBAAA;EACA,uBAAA;EACA,4BAAA;;AAEF,WA3CF,SA2CG,YAAa;EACZ,MAAA;EACA,UAAA;EACA,gBAAA;EACA,uBAAA;EACA,4BAAA;;AAEF,WAlDF,SAkDG,aAAc;EACb,MAAA;EACA,SAAA;EACA,gBAAA;EACA,uBAAA;EACA,4BAAA;;AH9FJ,WA4DC,SAAQ;EK9DP,UAAA;EAGA,0BAAA;;ALDF,WAgEC;EACC,iBAAA;EACA,gBAAA","file":"laps.css"}
+1
View File
@@ -0,0 +1 @@
#wpadminbar #wp-admin-bar-laps .ab-sub-wrapper{min-width:90%;width:90%;position:fixed;left:5%}#wpadminbar #wp-admin-bar-laps .ab-submenu{padding:0}#wpadminbar #wp-admin-bar-laps_output{padding:0 10px}#wpadminbar #wp-admin-bar-laps_output:hover{background-color:transparent}#wpadminbar #wp-admin-bar-laps_output .ab-empty-item{display:none}#wpadminbar .laps-timeline{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);margin:6px 0;position:relative}#wpadminbar .laps-timeline .event{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#ffffff;text-align:center;background-color:#5bc0de;-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;position:absolute;border-left:1px solid #f5f5f5;min-width:2px}#wpadminbar .laps-timeline .event-theme{background-color:#5cb85c}#wpadminbar .laps-timeline .event-plugin{background-color:#428bca}#wpadminbar .laps-timeline .event-core{background-color:#f0ad4e}#wpadminbar .laps-timeline .event-query{background-color:#5bc0de}#wpadminbar .laps-timeline .event-http{background-color:#d9534f}#wpadminbar .tooltip{position:absolute;z-index:100000;display:block;font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;font-size:12px;font-weight:normal;line-height:1.4;opacity:0;filter:alpha(opacity=0)}#wpadminbar .tooltip.in{opacity:0.9;filter:alpha(opacity=90)}#wpadminbar .tooltip.top{margin-top:-3px;padding:5px 0}#wpadminbar .tooltip.right{margin-left:3px;padding:0 5px}#wpadminbar .tooltip.bottom{margin-top:3px;padding:5px 0}#wpadminbar .tooltip.left{margin-left:-3px;padding:0 5px}#wpadminbar .tooltip-inner{max-width:300px;padding:3px 8px;color:#cccccc;text-align:center;text-decoration:none;background-color:#464646;border-radius:4px}#wpadminbar .tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}#wpadminbar .tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#464646}#wpadminbar .tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#464646}#wpadminbar .tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#464646}#wpadminbar .tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#464646}#wpadminbar .tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#464646}#wpadminbar .tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#464646}#wpadminbar .tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#464646}#wpadminbar .tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#464646}#wpadminbar .tooltip.in{opacity:1;filter:alpha(opacity=100)}#wpadminbar .tooltip-inner{line-height:20px;text-align:left}
+82 -54
View File
@@ -1,15 +1,13 @@
/* ======================================================================== /* ========================================================================
* Bootstrap: tooltip.js v3.2.0 * Bootstrap: tooltip.js v3.3.4
* http://getbootstrap.com/javascript/#tooltip * http://getbootstrap.com/javascript/#tooltip
* Inspired by the original jQuery.tipsy by Jason Frame * Inspired by the original jQuery.tipsy by Jason Frame
* ======================================================================== * ========================================================================
* Copyright 2011-2014 Twitter, Inc. * Copyright 2011-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */ * ======================================================================== */
// modified to use lapstooltip as plugin name
+function ($) { +function ($) {
'use strict'; 'use strict';
@@ -17,17 +15,19 @@
// =============================== // ===============================
var Tooltip = function (element, options) { var Tooltip = function (element, options) {
this.type = this.type = null
this.options = this.options = null
this.enabled = this.enabled = null
this.timeout = this.timeout = null
this.hoverState = this.hoverState = null
this.$element = null this.$element = null
this.init('lapstooltip', element, options) this.init('tooltip', element, options)
} }
Tooltip.VERSION = '3.2.0' Tooltip.VERSION = '3.3.4'
Tooltip.TRANSITION_DURATION = 150
Tooltip.DEFAULTS = { Tooltip.DEFAULTS = {
animation: true, animation: true,
@@ -52,6 +52,10 @@
this.options = this.getOptions(options) this.options = this.getOptions(options)
this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
if (this.$element[0] instanceof document.constructor && !this.options.selector) {
throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
}
var triggers = this.options.trigger.split(' ') var triggers = this.options.trigger.split(' ')
for (var i = triggers.length; i--;) { for (var i = triggers.length; i--;) {
@@ -105,6 +109,11 @@
var self = obj instanceof this.constructor ? var self = obj instanceof this.constructor ?
obj : $(obj.currentTarget).data('bs.' + this.type) obj : $(obj.currentTarget).data('bs.' + this.type)
if (self && self.$tip && self.$tip.is(':visible')) {
self.hoverState = 'in'
return
}
if (!self) { if (!self) {
self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
$(obj.currentTarget).data('bs.' + this.type, self) $(obj.currentTarget).data('bs.' + this.type, self)
@@ -147,7 +156,7 @@
if (this.hasContent() && this.enabled) { if (this.hasContent() && this.enabled) {
this.$element.trigger(e) this.$element.trigger(e)
var inDom = $.contains(document.documentElement, this.$element[0]) var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
if (e.isDefaultPrevented() || !inDom) return if (e.isDefaultPrevented() || !inDom) return
var that = this var that = this
@@ -183,13 +192,13 @@
if (autoPlace) { if (autoPlace) {
var orgPlacement = placement var orgPlacement = placement
var $parent = this.$element.parent() var $container = this.options.container ? $(this.options.container) : this.$element.parent()
var parentDim = this.getPosition($parent) var containerDim = this.getPosition($container)
placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' : placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' :
placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' : placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' :
placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' : placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' :
placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' : placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' :
placement placement
$tip $tip
@@ -202,14 +211,17 @@
this.applyPlacement(calculatedOffset, placement) this.applyPlacement(calculatedOffset, placement)
var complete = function () { var complete = function () {
var prevHoverState = that.hoverState
that.$element.trigger('shown.bs.' + that.type) that.$element.trigger('shown.bs.' + that.type)
that.hoverState = null that.hoverState = null
if (prevHoverState == 'out') that.leave(that)
} }
$.support.transition && this.$tip.hasClass('fade') ? $.support.transition && this.$tip.hasClass('fade') ?
$tip $tip
.one('bsTransitionEnd', complete) .one('bsTransitionEnd', complete)
.emulateTransitionEnd(150) : .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
complete() complete()
} }
} }
@@ -256,16 +268,18 @@
if (delta.left) offset.left += delta.left if (delta.left) offset.left += delta.left
else offset.top += delta.top else offset.top += delta.top
var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight var isVertical = /top|bottom/.test(placement)
var arrowPosition = delta.left ? 'left' : 'top' var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight' var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
$tip.offset(offset) $tip.offset(offset)
this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition) this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
} }
Tooltip.prototype.replaceArrow = function (delta, dimension, position) { Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '') this.arrow()
.css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
.css(isVertical ? 'top' : 'left', '')
} }
Tooltip.prototype.setContent = function () { Tooltip.prototype.setContent = function () {
@@ -276,16 +290,17 @@
$tip.removeClass('fade in top bottom left right') $tip.removeClass('fade in top bottom left right')
} }
Tooltip.prototype.hide = function () { Tooltip.prototype.hide = function (callback) {
var that = this var that = this
var $tip = this.tip() var $tip = $(this.$tip)
var e = $.Event('hide.bs.' + this.type) var e = $.Event('hide.bs.' + this.type)
this.$element.removeAttr('aria-describedby')
function complete() { function complete() {
if (that.hoverState != 'in') $tip.detach() if (that.hoverState != 'in') $tip.detach()
that.$element.trigger('hidden.bs.' + that.type) that.$element
.removeAttr('aria-describedby')
.trigger('hidden.bs.' + that.type)
callback && callback()
} }
this.$element.trigger(e) this.$element.trigger(e)
@@ -294,10 +309,10 @@
$tip.removeClass('in') $tip.removeClass('in')
$.support.transition && this.$tip.hasClass('fade') ? $.support.transition && $tip.hasClass('fade') ?
$tip $tip
.one('bsTransitionEnd', complete) .one('bsTransitionEnd', complete)
.emulateTransitionEnd(150) : .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
complete() complete()
this.hoverState = null this.hoverState = null
@@ -318,13 +333,20 @@
Tooltip.prototype.getPosition = function ($element) { Tooltip.prototype.getPosition = function ($element) {
$element = $element || this.$element $element = $element || this.$element
var el = $element[0] var el = $element[0]
var isBody = el.tagName == 'BODY' var isBody = el.tagName == 'BODY'
return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, {
scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(), var elRect = el.getBoundingClientRect()
width: isBody ? $(window).width() : $element.outerWidth(), if (elRect.width == null) {
height: isBody ? $(window).height() : $element.outerHeight() // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
}, isBody ? { top: 0, left: 0 } : $element.offset()) elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
}
var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
return $.extend({}, elRect, scroll, outerDims, elOffset)
} }
Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
@@ -388,14 +410,6 @@
return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
} }
Tooltip.prototype.validate = function () {
if (!this.$element[0].parentNode) {
this.hide()
this.$element = null
this.options = null
}
}
Tooltip.prototype.enable = function () { Tooltip.prototype.enable = function () {
this.enabled = true this.enabled = true
} }
@@ -422,8 +436,11 @@
} }
Tooltip.prototype.destroy = function () { Tooltip.prototype.destroy = function () {
var that = this
clearTimeout(this.timeout) clearTimeout(this.timeout)
this.hide().$element.off('.' + this.type).removeData('bs.' + this.type) this.hide(function () {
that.$element.off('.' + that.type).removeData('bs.' + that.type)
})
} }
@@ -433,27 +450,38 @@
function Plugin(option) { function Plugin(option) {
return this.each(function () { return this.each(function () {
var $this = $(this) var $this = $(this)
var data = $this.data('bs.lapstooltip') var data = $this.data('bs.tooltip')
var options = typeof option == 'object' && option var options = typeof option == 'object' && option
if (!data && option == 'destroy') return if (!data && /destroy|hide/.test(option)) return
if (!data) $this.data('bs.lapstooltip', (data = new Tooltip(this, options))) if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
if (typeof option == 'string') data[option]() if (typeof option == 'string') data[option]()
}) })
} }
var old = $.fn.lapstooltip var old = $.fn.tooltip
$.fn.lapstooltip = Plugin $.fn.tooltip = Plugin
$.fn.lapstooltip.Constructor = Tooltip $.fn.tooltip.Constructor = Tooltip
// TOOLTIP NO CONFLICT // TOOLTIP NO CONFLICT
// =================== // ===================
$.fn.lapstooltip.noConflict = function () { $.fn.tooltip.noConflict = function () {
$.fn.lapstooltip = old $.fn.tooltip = old
return this return this
} }
}(jQuery); }(jQuery);
jQuery.fn.lapstooltip = jQuery.fn.tooltip.noConflict();
jQuery(document).ready(function () {
jQuery(".laps-timeline .event").lapstooltip({
container: '#wpadminbar',
placement: 'bottom',
html : true,
animation: false
});
});
+5
View File
@@ -0,0 +1,5 @@
+function(t){'use strict';var e=function(t,e){this.type=null;this.options=null;this.enabled=null;this.timeout=null;this.hoverState=null;this.t$=null;this.init('tooltip',t,e)};e.VERSION='3.3.4';e.TRANSITION_DURATION=150;e.DEFAULTS={animation:!0,placement:'top',selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:'hover focus',title:'',delay:0,html:!1,container:!1,viewport:{selector:'body',padding:0}};e.prototype.init=function(e,i,s){this.enabled=!0;this.type=e;this.t$=t(i);this.options=this.getOptions(s);this.o$=this.options.viewport&&t(this.options.viewport.selector||this.options.viewport);if(this.t$[0]instanceof document.constructor&&!this.options.selector){throw new Error('`selector` option must be specified when initializing '+this.type+' on the window.document object!')};var r=this.options.trigger.split(' ');for(var n=r.length;n--;){var o=r[n];if(o=='click'){this.t$.on('click.'+this.type,this.options.selector,t.proxy(this.toggle,this))}
else if(o!='manual'){var a=o=='hover'?'mouseenter':'focusin',l=o=='hover'?'mouseleave':'focusout';this.t$.on(a+'.'+this.type,this.options.selector,t.proxy(this.enter,this));this.t$.on(l+'.'+this.type,this.options.selector,t.proxy(this.leave,this))}};this.options.selector?(this.i$=t.extend({},this.options,{trigger:'manual',selector:''})):this.fixTitle()};e.prototype.getDefaults=function(){return e.DEFAULTS};e.prototype.getOptions=function(e){e=t.extend({},this.getDefaults(),this.t$.data(),e);if(e.delay&&typeof e.delay=='number'){e.delay={show:e.delay,hide:e.delay}};return e};e.prototype.getDelegateOptions=function(){var e={};var i=this.getDefaults();this.i$&&t.each(this.i$,function(t,o){if(i[t]!=o)e[t]=o});return e};e.prototype.enter=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data('bs.'+this.type);if(i&&i.e$&&i.e$.is(':visible')){i.hoverState='in';return};if(!i){i=new this.constructor(e.currentTarget,this.getDelegateOptions());t(e.currentTarget).data('bs.'+this.type,i)};clearTimeout(i.timeout);i.hoverState='in';if(!i.options.delay||!i.options.delay.show)return i.show();i.timeout=setTimeout(function(){if(i.hoverState=='in')i.show()},i.options.delay.show)};e.prototype.leave=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data('bs.'+this.type);if(!i){i=new this.constructor(e.currentTarget,this.getDelegateOptions());t(e.currentTarget).data('bs.'+this.type,i)};clearTimeout(i.timeout);i.hoverState='out';if(!i.options.delay||!i.options.delay.hide)return i.hide();i.timeout=setTimeout(function(){if(i.hoverState=='out')i.hide()},i.options.delay.hide)};e.prototype.show=function(){var u=t.Event('show.bs.'+this.type);if(this.hasContent()&&this.enabled){this.t$.trigger(u);var d=t.contains(this.t$[0].ownerDocument.documentElement,this.t$[0]);if(u.isDefaultPrevented()||!d)return;var s=this,o=this.tip(),c=this.getUID(this.type);this.setContent();o.attr('id',c);this.t$.attr('aria-describedby',c);if(this.options.animation)o.addClass('fade');var i=typeof this.options.placement=='function'?this.options.placement.call(this,o[0],this.t$[0]):this.options.placement,f=/\s?auto?\s?/i,h=f.test(i);if(h)i=i.replace(f,'')||'top';o.detach().css({top:0,left:0,display:'block'}).addClass(i).data('bs.'+this.type,this);this.options.container?o.appendTo(this.options.container):o.insertAfter(this.t$);var n=this.getPosition(),a=o[0].offsetWidth,l=o[0].offsetHeight;if(h){var g=i,y=this.options.container?t(this.options.container):this.t$.parent(),r=this.getPosition(y);i=i=='bottom'&&n.bottom+l>r.bottom?'top':i=='top'&&n.top-l<r.top?'bottom':i=='right'&&n.right+a>r.width?'left':i=='left'&&n.left-a<r.left?'right':i;o.removeClass(g).addClass(i)};var v=this.getCalculatedOffset(i,n,a,l);this.applyPlacement(v,i);var p=function(){var t=s.hoverState;s.t$.trigger('shown.bs.'+s.type);s.hoverState=null;if(t=='out')s.leave(s)};t.support.transition&&this.e$.hasClass('fade')?o.one('bsTransitionEnd',p).emulateTransitionEnd(e.TRANSITION_DURATION):p()}};e.prototype.applyPlacement=function(e,o){var i=this.tip(),u=i[0].offsetWidth,p=i[0].offsetHeight,r=parseInt(i.css('margin-top'),10),l=parseInt(i.css('margin-left'),10);if(isNaN(r))r=0;if(isNaN(l))l=0;e.top=e.top+r;e.left=e.left+l;t.offset.setOffset(i[0],t.extend({using:function(t){i.css({top:Math.round(t.top),left:Math.round(t.left)})}},e),0);i.addClass('in');var h=i[0].offsetWidth,n=i[0].offsetHeight;if(o=='top'&&n!=p){e.top=e.top+p-n};var s=this.getViewportAdjustedDelta(o,e,h,n);if(s.left)e.left+=s.left;else e.top+=s.top;var a=/top|bottom/.test(o),f=a?s.left*2-u+h:s.top*2-p+n,c=a?'offsetWidth':'offsetHeight';i.offset(e);this.replaceArrow(f,i[0][c],a)};e.prototype.replaceArrow=function(t,e,i){this.arrow().css(i?'left':'top',50*(1-t/e)+'%').css(i?'top':'left','')};e.prototype.setContent=function(){var t=this.tip(),e=this.getTitle();t.find('.tooltip-inner')[this.options.html?'html':'text'](e);t.removeClass('fade in top bottom left right')};e.prototype.hide=function(i){var s=this,o=t(this.e$),r=t.Event('hide.bs.'+this.type);function n(){if(s.hoverState!='in')o.detach();s.t$.removeAttr('aria-describedby').trigger('hidden.bs.'+s.type);i&&i()};this.t$.trigger(r);if(r.isDefaultPrevented())return;o.removeClass('in');t.support.transition&&o.hasClass('fade')?o.one('bsTransitionEnd',n).emulateTransitionEnd(e.TRANSITION_DURATION):n();this.hoverState=null;return this};e.prototype.fixTitle=function(){var t=this.t$;if(t.attr('title')||typeof(t.attr('data-original-title'))!='string'){t.attr('data-original-title',t.attr('title')||'').attr('title','')}};e.prototype.hasContent=function(){return this.getTitle()};e.prototype.getPosition=function(e){e=e||this.t$;var s=e[0],o=s.tagName=='BODY',i=s.getBoundingClientRect();if(i.width==null){i=t.extend({},i,{width:i.right-i.left,height:i.bottom-i.top})};var n=o?{top:0,left:0}:e.offset();var a={scroll:o?document.documentElement.scrollTop||document.body.scrollTop:e.scrollTop()};var r=o?{width:t(window).width(),height:t(window).height()}:null;retuLine truncated
else if(r>e.top+e.height){o.top=e.top+e.height-r}}
else{var p=i.left-s,a=i.left+s+n;if(p<e.left){o.left=e.left-p}
else if(a>e.width){o.left=e.left+e.width-a}};return o};e.prototype.getTitle=function(){var i,e=this.t$,t=this.options;i=e.attr('data-original-title')||(typeof t.title=='function'?t.title.call(e[0]):t.title);return i};e.prototype.getUID=function(t){do t+=~~(Math.random()*1000000);while(document.getElementById(t))return t};e.prototype.tip=function(){return(this.e$=this.e$||t(this.options.template))};e.prototype.arrow=function(){return(this.s$=this.s$||this.tip().find('.tooltip-arrow'))};e.prototype.enable=function(){this.enabled=!0};e.prototype.disable=function(){this.enabled=!1};e.prototype.toggleEnabled=function(){this.enabled=!this.enabled};e.prototype.toggle=function(e){var i=this;if(e){i=t(e.currentTarget).data('bs.'+this.type);if(!i){i=new this.constructor(e.currentTarget,this.getDelegateOptions());t(e.currentTarget).data('bs.'+this.type,i)}};i.tip().hasClass('in')?i.leave(i):i.enter(i)};e.prototype.destroy=function(){var t=this;clearTimeout(this.timeout);this.hide(function(){t.t$.off('.'+t.type).removeData('bs.'+t.type)})};function i(i){return this.each(function(){var s=t(this),o=s.data('bs.tooltip'),n=typeof i=='object'&&i;if(!o&&/destroy|hide/.test(i))return;if(!o)s.data('bs.tooltip',(o=new e(this,n)));if(typeof i=='string')o[i]()})};var o=t.fn.tooltip;t.fn.tooltip=i;t.fn.tooltip.Constructor=e;t.fn.tooltip.noConflict=function(){t.fn.tooltip=o;return this}}(jQuery);jQuery.fn.lapstooltip=jQuery.fn.tooltip.noConflict();jQuery(document).ready(function(){jQuery('.laps-timeline .event').lapstooltip({container:'#wpadminbar',placement:'bottom',html:!0,animation:!1})});
+11
View File
@@ -0,0 +1,11 @@
jQuery.fn.lapstooltip = jQuery.fn.tooltip.noConflict();
jQuery(document).ready(function () {
jQuery(".laps-timeline .event").lapstooltip({
container: '#wpadminbar',
placement: 'bottom',
html : true,
animation: false
});
});
+3 -2
View File
@@ -4,7 +4,7 @@ Plugin Name: Laps
Plugin URI: https://github.com/Rarst/laps Plugin URI: https://github.com/Rarst/laps
Description: Light WordPress profiler. Description: Light WordPress profiler.
Author: Andrey "Rarst" Savchenko Author: Andrey "Rarst" Savchenko
Version: Version: 1.3.2
Author URI: http://www.rarst.net/ Author URI: http://www.rarst.net/
Text Domain: laps Text Domain: laps
Domain Path: /lang Domain Path: /lang
@@ -29,7 +29,8 @@ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) {
require __DIR__ . '/vendor/autoload.php'; require __DIR__ . '/vendor/autoload.php';
}
Rarst\Laps\Laps::on_load(); Rarst\Laps\Laps::on_load();
+12 -1
View File
@@ -14,12 +14,23 @@ class Core_Events extends Laps_Events {
$stops = array(); $stops = array();
$stops['plugins_loaded'][20] = array( $stops['plugins_loaded'][ - 2 ] = array(
'action' => 'stop', 'action' => 'stop',
'event' => 'Plugins Load', 'event' => 'Plugins Load',
'category' => 'plugin', 'category' => 'plugin',
); );
$stops['plugins_loaded'][ - 1 ] = array(
'event' => 'Plugins Loaded Hook',
'category' => 'plugin',
);
$stops['plugins_loaded'][20] = array(
'action' => 'stop',
'event' => 'Plugins Loaded Hook',
'category' => 'plugin',
);
$stops['setup_theme'][0] = array( $stops['setup_theme'][0] = array(
'event' => 'Themes Load', 'event' => 'Themes Load',
'category' => 'theme', 'category' => 'theme',
+1 -1
View File
@@ -14,7 +14,7 @@ class Hybrid_Events extends Laps_Events {
*/ */
protected function is_applicable() { protected function is_applicable() {
return defined( 'HYBRID_VERSION' ); return defined( 'HYBRID_VERSION' ) && function_exists( 'hybrid_get_prefix' );
} }
/** /**
+19 -36
View File
@@ -102,7 +102,11 @@ class Laps {
) )
); );
self::$stopwatch->$event['action']( $event['event'], $event['category'] ); if ( 'stop' === $event['action'] && ! self::$stopwatch->isStarted( $event['event'] ) ) {
return $input;
}
self::$stopwatch->{$event['action']}( $event['event'], $event['category'] );
return $input; return $input;
} }
@@ -162,13 +166,13 @@ class Laps {
} }
/** /**
* When theme is done possibly add theme-specific events. * When theme is done possibly add vendor-specific events.
*/ */
static function after_setup_theme() { static function after_setup_theme() {
foreach ( array( 'THA', 'Hybrid', 'Genesis', 'Thematic' ) as $theme ) { foreach ( array( 'THA', 'Hybrid', 'Genesis', 'Thematic', 'Yoast' ) as $vendor ) {
$class = "Rarst\\Laps\\{$theme}_Events"; $class = "Rarst\\Laps\\{$vendor}_Events";
/** @var Laps_Events $events */ /** @var Laps_Events $events */
$events = new $class; $events = new $class;
self::add_events( $events->get() ); self::add_events( $events->get() );
@@ -180,36 +184,20 @@ class Laps {
add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) ); add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) );
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) ); add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) );
add_action( 'admin_bar_menu', array( __CLASS__, 'admin_bar_menu' ), 100 ); add_action( 'admin_bar_menu', array( __CLASS__, 'admin_bar_menu' ), 100 );
add_action( 'wp_print_footer_scripts', array( __CLASS__, 'print_footer_scripts' ), 11 );
add_action( 'admin_print_footer_scripts', array( __CLASS__, 'print_footer_scripts' ), 11 );
} }
static function enqueue_scripts() { static function enqueue_scripts() {
wp_register_script( 'laps-tooltip', plugins_url( 'js/tooltip.js', __DIR__ ), array( 'jquery' ), '3.0.2', true ); $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
wp_register_style( 'laps', plugins_url( 'css/laps.css', __DIR__ ) ); wp_register_script( 'laps', plugins_url( "js/laps{$suffix}.js", __DIR__ ), array( 'jquery' ), '3.3.1', true );
wp_register_style( 'laps', plugins_url( "css/laps{$suffix}.css", __DIR__ ) );
if ( is_admin_bar_showing() ) { if ( is_admin_bar_showing() ) {
wp_enqueue_script( 'laps-tooltip' ); wp_enqueue_script( 'laps' );
wp_enqueue_style( 'laps' ); wp_enqueue_style( 'laps' );
} }
} }
static function print_footer_scripts() {
if ( wp_script_is( 'laps-tooltip', 'done' ) ) {
?>
<script type="text/javascript">
jQuery(document).ready(function () {
jQuery(".laps-timeline .event").lapstooltip({
container: '#wpadminbar', placement: 'bottom', html: true, animation: false
// , trigger: 'click'
});
});
</script><?php
}
}
/** /**
* Render interface and add to the toolbar. * Render interface and add to the toolbar.
* *
@@ -226,6 +214,7 @@ class Laps {
$mustache = new \Mustache_Engine( $mustache = new \Mustache_Engine(
array( array(
'loader' => new \Mustache_Loader_FilesystemLoader( dirname( __DIR__ ) . '/views' ), 'loader' => new \Mustache_Loader_FilesystemLoader( dirname( __DIR__ ) . '/views' ),
'cache' => new Mustache_Cache_FrozenCache( dirname( __DIR__ ) . '/views/cache' ),
) )
); );
@@ -245,7 +234,7 @@ class Laps {
$width = round( $duration / $total * 100, 2 ); $width = round( $duration / $total * 100, 2 );
$category = $event->getCategory(); $category = $event->getCategory();
if ( 'http' == $category ) { if ( 'http' === $category ) {
$http_data[] = compact( 'name', 'offset', 'duration', 'width', 'category' ); $http_data[] = compact( 'name', 'offset', 'duration', 'width', 'category' );
continue; continue;
} }
@@ -271,7 +260,7 @@ class Laps {
$offset = round( ( $query_start - $start ) / $total * 100, 2 ); $offset = round( ( $query_start - $start ) / $total * 100, 2 );
// if query is indistinguishably close to previous then stack it // if query is indistinguishably close to previous then stack it
if ( $offset == $last_offset ) { if ( $offset === $last_offset ) {
$key = count( $query_data ) - 1; $key = count( $query_data ) - 1;
$query_data[ $key ]['sql'] .= '<br />' . $sql; $query_data[ $key ]['sql'] .= '<br />' . $sql;
@@ -290,8 +279,6 @@ class Laps {
} }
} }
// !d( self::$query_starts, $wpdb->queries, $query_data );
$html = $mustache->render( $html = $mustache->render(
'laps', 'laps',
array( array(
@@ -303,19 +290,15 @@ class Laps {
) )
); );
$wp_admin_bar->add_node( $wp_admin_bar->add_node( array(
array(
'id' => 'laps', 'id' => 'laps',
'title' => sprintf( 'Lap: %ss', round( $total / 1000, 3 ) ), 'title' => sprintf( 'Lap: %ss', round( $total / 1000, 3 ) ),
) ) );
);
$wp_admin_bar->add_node( $wp_admin_bar->add_node( array(
array(
'id' => 'laps_output', 'id' => 'laps_output',
'parent' => 'laps', 'parent' => 'laps',
'meta' => array( 'html' => $html ), 'meta' => array( 'html' => $html ),
) ) );
);
} }
} }
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace Rarst\Laps;
/**
* Implements read-only filesystem cache
*/
class Mustache_Cache_FrozenCache extends \Mustache_Cache_FilesystemCache {
/**
* Cache and load a compiled Mustache_Template class.
*
* @param string $key
* @param string $value
*
* @return void
*/
public function cache( $key, $value ) {
$this->log(
\Mustache_Logger::WARNING,
'Read only cache file missing, evaluating "{className}" class at runtime',
array( 'className' => $key )
);
eval( '?>' . $value );
}
}
+38
View File
@@ -0,0 +1,38 @@
<?php
namespace Rarst\Laps;
/**
* Events for Yoast plugins
*/
class Yoast_Events extends Laps_Events {
/**
* @return bool
*/
protected function is_applicable() {
return class_exists( 'WPSEO_Frontend' );
}
/**
* @return array
*/
public function get_events() {
$stops = array();
$stops['wpseo_head'][1] = array(
'event' => 'WP SEO head hook',
'category' => 'plugin',
);
$stops['wpseo_head'][100] = array(
'action' => 'stop',
'event' => 'WP SEO head hook',
'category' => 'plugin',
);
return $stops;
}
}
@@ -0,0 +1,241 @@
<?php
class __Mustache_37c708633787b0bcaf1bd7b4adc8b13a extends Mustache_Template
{
private $lambdaHelper;
public function renderInternal(Mustache_Context $context, $indent = '')
{
$this->lambdaHelper = new Mustache_LambdaHelper($this->mustache, $context);
$buffer = '';
$newContext = array();
$buffer .= $indent . '<div class="laps-timeline">
';
// 'events' section
$value = $context->find('events');
$buffer .= $this->section83708baddd3627fe4d26675ddf7eaeb5($context, $indent, $value);
$buffer .= $indent . '</div>
';
$buffer .= $indent . '
';
// 'savequeries' section
$value = $context->find('savequeries');
$buffer .= $this->section9756eb1d93d100052bdb80ee49b09ad6($context, $indent, $value);
$buffer .= $indent . '
';
// 'savehttp' section
$value = $context->find('savehttp');
$buffer .= $this->section3669ef98d4f6390c8df9645c96a328ee($context, $indent, $value);
return $buffer;
}
private function section83708baddd3627fe4d26675ddf7eaeb5(Mustache_Context $context, $indent, $value)
{
$buffer = '';
if (!is_string($value) && is_callable($value)) {
$source = '
<div class="event event-{{category}}" data-toggle="tooltip" title="{{name}} - {{duration}} ms - {{memory}} MB" style="width:{{width}}%; left:{{offset}}%;"></div>
';
$result = call_user_func($value, $source, $this->lambdaHelper);
if (strpos($result, '{{') === false) {
$buffer .= $result;
} else {
$buffer .= $this->mustache
->loadLambda((string) $result)
->renderInternal($context);
}
} elseif (!empty($value)) {
$values = $this->isIterable($value) ? $value : array($value);
foreach ($values as $value) {
$context->push($value);
$buffer .= $indent . ' <div class="event event-';
$value = $this->resolveValue($context->find('category'), $context, $indent);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '" data-toggle="tooltip" title="';
$value = $this->resolveValue($context->find('name'), $context, $indent);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= ' - ';
$value = $this->resolveValue($context->find('duration'), $context, $indent);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= ' ms - ';
$value = $this->resolveValue($context->find('memory'), $context, $indent);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= ' MB" style="width:';
$value = $this->resolveValue($context->find('width'), $context, $indent);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '%; left:';
$value = $this->resolveValue($context->find('offset'), $context, $indent);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '%;"></div>
';
$context->pop();
}
}
return $buffer;
}
private function section8dd7d0439d6fbb51dfb44aaa94780d5c(Mustache_Context $context, $indent, $value)
{
$buffer = '';
if (!is_string($value) && is_callable($value)) {
$source = '
<div class="event event-{{category}}" title="{{sql}}" style="width:{{width}}%; left:{{offset}}%;"></div>
';
$result = call_user_func($value, $source, $this->lambdaHelper);
if (strpos($result, '{{') === false) {
$buffer .= $result;
} else {
$buffer .= $this->mustache
->loadLambda((string) $result)
->renderInternal($context);
}
} elseif (!empty($value)) {
$values = $this->isIterable($value) ? $value : array($value);
foreach ($values as $value) {
$context->push($value);
$buffer .= $indent . ' <div class="event event-';
$value = $this->resolveValue($context->find('category'), $context, $indent);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '" title="';
$value = $this->resolveValue($context->find('sql'), $context, $indent);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '" style="width:';
$value = $this->resolveValue($context->find('width'), $context, $indent);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '%; left:';
$value = $this->resolveValue($context->find('offset'), $context, $indent);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '%;"></div>
';
$context->pop();
}
}
return $buffer;
}
private function section9756eb1d93d100052bdb80ee49b09ad6(Mustache_Context $context, $indent, $value)
{
$buffer = '';
if (!is_string($value) && is_callable($value)) {
$source = '
<div class="laps-timeline">
{{#queries}}
<div class="event event-{{category}}" title="{{sql}}" style="width:{{width}}%; left:{{offset}}%;"></div>
{{/queries}}
</div>
';
$result = call_user_func($value, $source, $this->lambdaHelper);
if (strpos($result, '{{') === false) {
$buffer .= $result;
} else {
$buffer .= $this->mustache
->loadLambda((string) $result)
->renderInternal($context);
}
} elseif (!empty($value)) {
$values = $this->isIterable($value) ? $value : array($value);
foreach ($values as $value) {
$context->push($value);
$buffer .= $indent . '<div class="laps-timeline">
';
// 'queries' section
$value = $context->find('queries');
$buffer .= $this->section8dd7d0439d6fbb51dfb44aaa94780d5c($context, $indent, $value);
$buffer .= $indent . '</div>
';
$context->pop();
}
}
return $buffer;
}
private function sectionFb9cb3f90496dc38ba05f46e0ac2ad5d(Mustache_Context $context, $indent, $value)
{
$buffer = '';
if (!is_string($value) && is_callable($value)) {
$source = '
<div class="event event-{{category}}" title="{{name}} - {{duration}} ms" style="width:{{width}}%; left:{{offset}}%;"></div>
';
$result = call_user_func($value, $source, $this->lambdaHelper);
if (strpos($result, '{{') === false) {
$buffer .= $result;
} else {
$buffer .= $this->mustache
->loadLambda((string) $result)
->renderInternal($context);
}
} elseif (!empty($value)) {
$values = $this->isIterable($value) ? $value : array($value);
foreach ($values as $value) {
$context->push($value);
$buffer .= $indent . ' <div class="event event-';
$value = $this->resolveValue($context->find('category'), $context, $indent);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '" title="';
$value = $this->resolveValue($context->find('name'), $context, $indent);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= ' - ';
$value = $this->resolveValue($context->find('duration'), $context, $indent);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= ' ms" style="width:';
$value = $this->resolveValue($context->find('width'), $context, $indent);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '%; left:';
$value = $this->resolveValue($context->find('offset'), $context, $indent);
$buffer .= htmlspecialchars($value, 2, 'UTF-8');
$buffer .= '%;"></div>
';
$context->pop();
}
}
return $buffer;
}
private function section3669ef98d4f6390c8df9645c96a328ee(Mustache_Context $context, $indent, $value)
{
$buffer = '';
if (!is_string($value) && is_callable($value)) {
$source = '
<div class="laps-timeline">
{{#http}}
<div class="event event-{{category}}" title="{{name}} - {{duration}} ms" style="width:{{width}}%; left:{{offset}}%;"></div>
{{/http}}
</div>
';
$result = call_user_func($value, $source, $this->lambdaHelper);
if (strpos($result, '{{') === false) {
$buffer .= $result;
} else {
$buffer .= $this->mustache
->loadLambda((string) $result)
->renderInternal($context);
}
} elseif (!empty($value)) {
$values = $this->isIterable($value) ? $value : array($value);
foreach ($values as $value) {
$context->push($value);
$buffer .= $indent . '<div class="laps-timeline">
';
// 'http' section
$value = $context->find('http');
$buffer .= $this->sectionFb9cb3f90496dc38ba05f46e0ac2ad5d($context, $indent, $value);
$buffer .= $indent . '</div>
';
$context->pop();
}
}
return $buffer;
}
}