1
0
mirror of https://github.com/pattern-lab/patternlab-php.git synced 2025-01-17 22:29:12 +01:00

Merge branch 'dev' into feature-patternsearch

Conflicts:
	core/templates/index.mustache
This commit is contained in:
Dave Olsen 2014-02-22 12:23:33 -05:00
commit c94a368fa1
16 changed files with 692 additions and 137 deletions

View File

@ -37,6 +37,7 @@ class Builder {
protected $patternLineages; // the list of patterns that make up a particular pattern
protected $patternLineagesR; // the list of patterns where a particular pattern is used
protected $patternTypesRegex; // the simple regex for the pattern types. used in getPath()
protected $patternStates; // the states from the config to be used in the state comparison
protected $navItems; // the items for the nav. includes view all links
protected $viewAllPaths; // the paths to the view all pages
protected $enableCSS; // decide if we'll enable CSS parsing
@ -66,7 +67,7 @@ class Builder {
foreach ($config as $key => $value) {
// if the variables are array-like make sure the properties are validated/trimmed/lowercased before saving
if (($key == "ie") || ($key == "id")) {
if (($key == "ie") || ($key == "id") || ($key == "patternStates")) {
$values = explode(",",$value);
array_walk($values,'PatternLab\Builder::trim');
$this->$key = $values;
@ -437,10 +438,11 @@ class Builder {
if (count($foundLineages) > 0) {
foreach ($foundLineages as $lineage) {
$patternBits = explode("-",$lineage,2); // BUG: this is making an assumption
$patternBits = $this->getPatternInfo($lineage);
if ((count($patternBits) == 2) && isset($this->patternPaths[$patternBits[0]][$patternBits[1]])) {
$path = $this->patternPaths[$patternBits[0]][$patternBits[1]]["patternDestPath"];
$patternLineage[] = array("lineagePattern" => $lineage, "lineagePath" => "../../patterns/".$path."/".$path.".html");
$patternLineage[] = array("lineagePattern" => $lineage,
"lineagePath" => "../../patterns/".$path."/".$path.".html");
} else {
if (strpos($lineage, '/') === false) {
print "You may have a typo in ".$patternInfo["patternSrcPath"].". {{> ".$lineage." }} is not a valid pattern.\n";
@ -463,17 +465,28 @@ class Builder {
foreach ($this->patternLineages as $haystackPartial => $haystackLineages) {
foreach ($haystackLineages as $haystackLineage) {
if ($haystackLineage["lineagePattern"] == $needlePartial) {
$patternBits = explode("-",$haystackPartial,2); // BUG: this is making an assumption
if (isset($this->patternPaths[$patternBits[0]][$patternBits[1]])) {
$path = $this->patternPaths[$patternBits[0]][$patternBits[1]]["patternDestPath"];
$patternLineageR[] = array("lineagePattern" => $haystackPartial, "lineagePath" => "../../patterns/".$path."/".$path.".html");
} else {
if (strpos($lineage, '/') === false) {
print "You may have a typo in ".$patternInfo["patternSrcPath"].". {{> ".$lineage." }} is not a valid pattern.\n";
$foundAlready = false;
foreach ($patternLineageR as $patternCheck) {
if ($patternCheck["lineagePattern"] == $haystackPartial) {
$foundAlready = true;
break;
}
}
if (!$foundAlready) {
$patternBits = $this->getPatternInfo($haystackPartial);
if (isset($this->patternPaths[$patternBits[0]][$patternBits[1]])) {
$path = $this->patternPaths[$patternBits[0]][$patternBits[1]]["patternDestPath"];
$patternLineageR[] = array("lineagePattern" => $haystackPartial,
"lineagePath" => "../../patterns/".$path."/".$path.".html");
}
}
}
}
}
@ -535,6 +548,9 @@ class Builder {
$patternObjects = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(__DIR__.$this->sp), \RecursiveIteratorIterator::SELF_FIRST);
$patternObjects->setFlags(\FilesystemIterator::SKIP_DOTS);
$patternObjects = iterator_to_array($patternObjects);
ksort($patternObjects);
foreach($patternObjects as $name => $object) {
$name = str_replace(__DIR__.$this->sp,"",$name);
@ -604,8 +620,16 @@ class Builder {
* Mustache patterns
*************************************/
$patternFull = $object->getFilename(); // 00-colors.mustache
$pattern = str_replace(".mustache","",$patternFull); // 00-colors
$patternFull = $object->getFilename(); // 00-colors.mustache
$pattern = str_replace(".mustache","",$patternFull); // 00-colors
// check for pattern state
$patternState = "";
if (strpos($pattern,"@") !== false) {
$patternBits = explode("@",$pattern,2);
$pattern = $patternBits[0];
$patternState = $patternBits[1];
}
if ($patternSubtypeSet) {
$patternPath = $patternType.$dirSep.$patternSubtype.$dirSep.$pattern; // 00-atoms/01-global/00-colors
@ -621,7 +645,7 @@ class Builder {
// make sure the pattern isn't hidden
if ($patternFull[0] != "_") {
// set-up the names
// set-up the names
$patternDash = $this->getPatternName($pattern,false); // colors
$patternClean = str_replace("-"," ",$patternDash); // colors (dashes replaced with spaces)
$patternPartial = $patternTypeDash."-".$patternDash; // atoms-colors
@ -630,6 +654,7 @@ class Builder {
$patternInfo = array("patternPath" => $patternPathDash."/".$patternPathDash.".html",
"patternSrcPath" => str_replace(__DIR__.$this->sp,"",$object->getPathname()),
"patternName" => ucwords($patternClean),
"patternState" => $patternState,
"patternPartial" => $patternPartial);
// add to the nav
@ -654,12 +679,17 @@ class Builder {
}
// add all patterns to patternPaths
$patternSrcPath = $patternPath;
$patternSrcPath = str_replace(__DIR__.$this->sp,"",str_replace(".mustache","",$object->getPathname()));
$patternDestPath = $patternPathDash;
$this->patternPaths[$patternTypeDash][$patternDash] = array("patternSrcPath" => $patternSrcPath, "patternDestPath" => $patternDestPath, "patternPartial" => $patternPartial, "render" => $render);
$this->patternPaths[$patternTypeDash][$patternDash] = array("patternSrcPath" => $patternSrcPath,
"patternDestPath" => $patternDestPath,
"patternPartial" => $patternPartial,
"patternState" => $patternState,
"patternType" => $patternTypeDash,
"render" => $render);
} else if ($object->isFile() && ($object->getExtension() == "json") && (strpos($object->getFilename(),"~") !== false)) {
/*************************************
* This section is for:
* JSON psuedo-patterns
@ -670,17 +700,27 @@ class Builder {
if ($patternFull[0] != "_") {
// check for a pattern state
$patternState = "";
$patternBits = explode("@",$patternFull,2);
if (isset($patternBits[1])) {
$patternState = str_replace(".json","",$patternBits[1]);
$patternFull = preg_replace("/@(.*?)\./",".",$patternFull);
}
// set-up the names
// $patternFull is defined above 00-colors.mustache
// $patternFull is defined above 00-colors.mustache
$patternBits = explode("~",$patternFull);
$patternBase = $patternBits[0].".mustache"; // 00-homepage.mustache
$patternBaseJSON = $patternBits[0].".json"; // 00-homepage.json
$patternBase = $patternBits[0].".mustache"; // 00-homepage.mustache
$patternBaseDash = $this->getPatternName($patternBits[0],false); // homepage
$patternBaseJSON = $patternBits[0].".json"; // 00-homepage.json
$stripJSON = str_replace(".json","",$patternBits[1]);
$pattern = $patternBits[0]."-".$stripJSON; // 00-homepage-00-emergency
$patternInt = $patternBits[0]."-".$this->getPatternName($stripJSON, false); // 00-homepage-emergency
$patternDash = $this->getPatternName($patternInt,false); // homepage-emergency
$patternClean = str_replace("-"," ",$patternDash); // homepage emergency
$patternPartial = $patternTypeDash."-".$patternDash; // pages-homepage-emergency
$patternBitClean = preg_replace("/@(.*?)/","",$patternBits[0]);
$pattern = $patternBitClean."-".$stripJSON; // 00-homepage-00-emergency
$patternInt = $patternBitClean."-".$this->getPatternName($stripJSON, false); // 00-homepage-emergency
$patternDash = $this->getPatternName($patternInt,false); // homepage-emergency
$patternClean = str_replace("-"," ",$patternDash); // homepage emergency
$patternPartial = $patternTypeDash."-".$patternDash; // pages-homepage-emergency
// add to patternPaths
if ($patternSubtypeSet) {
@ -692,14 +732,20 @@ class Builder {
}
// add all patterns to patternPaths
$patternSrcPath = str_replace(__DIR__.$this->sp,"",preg_replace("/\~(.*)\.json/","",$object->getPathname()));
$patternSrcPath = $this->patternPaths[$patternTypeDash][$patternBaseDash]["patternSrcPath"];
$patternDestPath = $patternPathDash;
$this->patternPaths[$patternTypeDash][$patternDash] = array("patternSrcPath" => $patternSrcPath, "patternDestPath" => $patternDestPath, "patternPartial" => $patternPartial, "render" => true);
$this->patternPaths[$patternTypeDash][$patternDash] = array("patternSrcPath" => $patternSrcPath,
"patternDestPath" => $patternDestPath,
"patternPartial" => $patternPartial,
"patternState" => $patternState,
"patternType" => $patternTypeDash,
"render" => true);
// set-up the info for the nav
$patternInfo = array("patternPath" => $patternPathDash."/".$patternPathDash.".html",
"patternSrcPath" => str_replace(__DIR__.$this->sp,"",preg_replace("/\~(.*)\.json/",".mustache",$object->getPathname())),
"patternName" => ucwords($patternClean),
"patternState" => $patternState,
"patternPartial" => $patternPartial);
// add to the nav
@ -773,6 +819,61 @@ class Builder {
// get all of the lineages
$this->gatherLineages();
// check on the states of the patterns
$patternStateLast = count($this->patternStates) - 1;
foreach($this->patternPaths as $patternType => $patterns) {
foreach ($patterns as $pattern => $patternInfo) {
$patternState = $this->patternPaths[$patternType][$pattern]["patternState"];
// make sure the pattern has a given state
if ($patternState != "") {
$patternStateDigit = array_search($patternState, $this->patternStates);
if ($patternStateDigit !== false) {
// iterate over each of the reverse lineages for a given pattern to update their state
foreach ($this->patternLineagesR[$patternType."-".$pattern] as $patternCheckInfo) {
$patternBits = $this->getPatternInfo($patternCheckInfo["lineagePattern"]);
if (($this->patternPaths[$patternBits[0]][$patternBits[1]]["patternState"] == "") && ($patternStateDigit != $patternStateLast)) {
$this->patternPaths[$patternBits[0]][$patternBits[1]]["patternState"] = $patternState;
} else {
$patternStateCheck = array_search($this->patternPaths[$patternBits[0]][$patternBits[1]]["patternState"], $this->patternStates);
if ($patternStateDigit < $patternStateCheck) {
$this->patternPaths[$patternBits[0]][$patternBits[1]]["patternState"] = $patternState;
}
}
}
}
}
}
}
// make sure we update the lineages with the pattern state if appropriate
foreach($this->patternLineages as $pattern => $patternLineages) {
foreach($patternLineages as $key => $patternLineageInfo) {
$patternBits = $this->getPatternInfo($patternLineageInfo["lineagePattern"]);
$patternState = $this->patternPaths[$patternBits[0]][$patternBits[1]]["patternState"];
if (($patternState != "") && ($patternState != null)) {
$this->patternLineages[$pattern][$key]["lineageState"] = $patternState;
}
}
}
foreach($this->patternLineagesR as $pattern => $patternLineages) {
foreach($patternLineages as $key => $patternLineageInfo) {
$patternBits = $this->getPatternInfo($patternLineageInfo["lineagePattern"]);
$patternState = $this->patternPaths[$patternBits[0]][$patternBits[1]]["patternState"];
if (($patternState != "") && ($patternState != null)) {
$this->patternLineagesR[$pattern][$key]["lineageState"] = $patternState;
}
}
}
// make sure $this->mpl is refreshed
$this->loadMustachePatternLoaderInstance();
@ -813,7 +914,7 @@ class Builder {
$this->viewAllPaths[$patternTypeDash][$patternSubtypeDash] = $patternType."-".$patternSubtype;
// add patterns to $this->patternPartials
foreach ($patternSubtypeValues["patternSubtypeItems"] as $patternSubtypeItem) {
foreach ($patternSubtypeValues["patternSubtypeItems"] as $patternSubtypeItemKey => $patternSubtypeItem) {
$patternCode = $this->renderPattern($patternSubtypeItem["patternSrcPath"],$patternSubtypeItem["patternPartial"]);
$patternCodeRaw = $patternCode[0];
@ -841,6 +942,12 @@ class Builder {
"patternLineages" => $patternLineages
);
// set the pattern state
$patternBits = $this->getPatternInfo($patternSubtypeItem["patternPartial"]);
if (($this->patternPaths[$patternBits[0]][$patternBits[1]]["patternState"] != "") && (isset($this->navItems["patternTypes"][$patternTypeKey]["patternTypeItems"][$patternSubtypeKey]["patternSubtypeItems"]))) {
$this->navItems["patternTypes"][$patternTypeKey]["patternTypeItems"][$patternSubtypeKey]["patternSubtypeItems"][$patternSubtypeItemKey]["patternState"] = $this->patternPaths[$patternBits[0]][$patternBits[1]]["patternState"];
}
}
}
@ -853,6 +960,15 @@ class Builder {
$arrayReset = false;
}
} else {
foreach ($patternTypeValues["patternItems"] as $patternSubtypeKey => $patternSubtypeItem) {
// set the pattern state
$patternBits = $this->getPatternInfo($patternSubtypeItem["patternPartial"]);
if ($this->patternPaths[$patternBits[0]][$patternBits[1]]["patternState"] != "") {
$this->navItems["patternTypes"][$patternTypeKey]["patternItems"][$patternSubtypeKey]["patternState"] = $this->patternPaths[$patternBits[0]][$patternBits[1]]["patternState"];
}
}
}
}
@ -951,6 +1067,33 @@ class Builder {
}
}
/**
* Helper function to return the parts of a partial name
* @param {String} the name of the partial
*
* @return {Array} the pattern type and the name of the pattern
*/
private function getPatternInfo($name) {
$patternBits = explode("-",$name);
$i = 1;
$k = 2;
$c = count($patternBits);
$patternType = $patternBits[0];
while (!isset($this->patternPaths[$patternType]) && ($i < $c)) {
$patternType .= "-".$patternBits[$i];
$i++;
$k++;
}
$patternBits = explode("-",$name,$k);
$pattern = $patternBits[count($patternBits)-1];
return array($patternType, $pattern);
}
/**
* Get the name for a given pattern sans any possible digits used for reordering
* @param {String} the pattern based on the filesystem name
@ -959,11 +1102,73 @@ class Builder {
* @return {String} a lower-cased version of the pattern name
*/
protected function getPatternName($pattern, $clean = true) {
$patternBits = explode("-",$pattern,2);
$patternBits = explode("-",$pattern,2);
$patternName = (((int)$patternBits[0] != 0) || ($patternBits[0] == '00')) ? $patternBits[1] : $pattern;
return ($clean) ? (str_replace("-"," ",$patternName)) : $patternName;
}
protected function setPatternState($patternState, $patternPartial) {
// set-up some defaults
$patternState = array_search($patternState, $this->patternStates);
// iterate over each of the reverse lineages for a given pattern to update their state
foreach ($this->patternLineagesR[$patternPartial] as $patternCheckInfo) {
// run through all of the navitems to find what pattern states match. this feels, and is, overkill
foreach ($this->navItems["patternTypes"] as $patternTypeKey => $patternTypeValues) {
if (isset($patternTypeValues["patternTypeItems"])) {
foreach ($patternTypeValues["patternTypeItems"] as $patternSubtypeKey => $patternSubtypeValues) {
// add patterns to $this->patternPartials
foreach ($patternSubtypeValues["patternSubtypeItems"] as $patternSubtypeItemKey => $patternSubtypeItem) {
if ($patternSubtypeItem["patternPartial"] == $patternPartial) {
if ($this->navItems["patternTypes"][$patternTypeKey]["patternTypeItems"][$patternSubtypeKey]["patternSubtypeItems"][$patternSubtypeItemKey]["patternState"] == "") {
$f = $patternState;
} else {
$patternCheckState = array_search($this->navItems["patternTypes"][$patternTypeKey]["patternTypeItems"][$patternSubtypeKey]["patternSubtypeItems"][$patternSubtypeItemKey]["patternState"], $this->patternStates);
if ($patternState < $patternCheckState) {
$this->navItems["patternTypes"][$patternTypeKey]["patternTypeItems"][$patternSubtypeKey]["patternSubtypeItems"][$patternSubtypeItemKey]["patternState"] = $patternState;
}
}
}
}
}
} else {
foreach ($patternTypeValues["patternItems"] as $patternSubtypeKey => $patternSubtypeItem) {
if ($patternSubtypeItem["patternPartial"] == $patternPartial) {
if ($this->navItems["patternTypes"][$patternTypeKey]["patternItems"][$patternSubtypeKey]["patternState"] == "") {
$this->navItems["patternTypes"][$patternTypeKey]["patternItems"][$patternSubtypeKey]["patternState"] = $patternState;
} else {
$patternCheckState = array_search($this->navItems["patternTypes"][$patternTypeKey]["patternItems"][$patternSubtypeKey]["patternState"], $this->patternStates);
if ($patternState < $patternCheckState) {
$this->navItems["patternTypes"][$patternTypeKey]["patternItems"][$patternSubtypeKey]["patternState"] = $patternState;
}
}
}
}
}
}
}
}
/**
* Write out the time tracking file so the content sync service will work. A holdover
* from how I put together the original AJAX polling set-up.

View File

@ -56,8 +56,7 @@ class Generator extends Builder {
// gather all of the various pattern info
$this->gatherPatternInfo();
// clean the public directory to remove old files
if ($this->cleanPublic == "true") {
$this->cleanPublic();

View File

@ -13,8 +13,10 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styleguide/css/styleguide.css?{{ cacheBuster }}" media="all" />
<link rel="stylesheet" href="styleguide/css/prism.css?{{ cacheBuster }}" media="all" />
<link rel="stylesheet" href="styleguide/css/typeahead.css?{{ cacheBuster }}" media="all" />
<link rel="stylesheet" href="styleguide/css/vendor/typeahead.css?{{ cacheBuster }}" media="all" />
<link rel="stylesheet" href="styleguide/css/states.css?{{ cacheBuster }}" media="all" />
<link rel="stylesheet" href="styleguide/css/vendor/prism.css?{{ cacheBuster }}" media="all" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="styleguide/js/vendor/jquery.js"><\/script>')</script>
</head>
@ -40,45 +42,24 @@
</div>
</div>
<!--end iFrame-->
<style>
#sg-code-markup {
padding-top: 10px;
}
#sg-code-tabs {
list-style: none;
margin: 0;
padding: 0;
}
#sg-code-tabs li {
float: left;
background-color: #333;
font-size: 1.3em;
font-weight: bold;
padding: 5px 15px;
border-top: 2px solid #666;
margin-right: 2px;
cursor: pointer;
}
.sg-code-title-active {
color: #bbb;
background-color: #272822 !important;
}
div.clear {
clear: both;
}
</style>
<!-- the template for the code view slider -->
<script type="text/html" id="code-template">
<a href="#" id="sg-code-close-btn" class="sg-view-close-btn">Close</a>
<div id="sg-code-close" class="sg-view-close">
<a href="#" id="sg-code-close-btn" class="sg-view-close-btn">Close</a>
</div>
<div id="sg-code-loader">
<div class="spinner"></div>
Loading pattern...
</div>
<div id="sg-code-lineage" style="display: none;">
<p>
This pattern contains the following patterns: <span id="sg-code-lineage-fill"></span>
The <span id="sg-code-lineager-patternname" class="sg-code-patternname"></span> pattern contains the following patterns: <span id="sg-code-lineage-fill"></span>
</p>
</div>
<div id="sg-code-lineager" style="display: none;">
<p>
This pattern is included in the following patterns: <span id="sg-code-lineager-fill"></span>
The <span id="sg-code-lineager-patternname" class="sg-code-patternname"></span> pattern is included in the following patterns: <span id="sg-code-lineager-fill"></span>
</p>
</div>
<div id="sg-code-markup">
@ -95,7 +76,9 @@
<!-- the template for the annotations viewer slider -->
<script type="text/html" id="annotations-template">
<a href="#" id="sg-annotation-close-btn" class="sg-view-close-btn">Close</a>
<div id="sg-annotation-close" class="sg-view-close">
<a href="#" id="sg-annotation-close-btn" class="sg-view-close-btn">Close</a>
</div>
<div id="sg-comments-container"></div>
</script>

View File

@ -2,14 +2,14 @@
{{# patternTypes }}
<li class="sg-nav-{{ patternTypeLC }}"><a class="sg-acc-handle">{{ patternTypeUC }}</a><ol class="sg-acc-panel">
{{# patternTypeItems }}
<li class="sg-nav-{{ patternSubtypeLC }}"><a class="sg-acc-handle">{{ patternSubtypeUC }}</a><ol class="sg-acc-panel">
<li class="sg-nav-{{ patternSubtypeLC }}"><a class="sg-acc-handle">{{ patternSubtypeUC }}</a><ol class="sg-acc-panel sg-sub-nav">
{{# patternSubtypeItems }}
<li><a href="patterns/{{ patternPath }}" class="sg-pop" data-patternpartial="{{ patternPartial }}">{{ patternName }}</a></li>
<li><a href="patterns/{{ patternPath }}" class="sg-pop {{# patternState }}sg-pattern-state {{ . }}{{/ patternState }}" data-patternpartial="{{ patternPartial }}">{{ patternName }}</a></li>
{{/ patternSubtypeItems }}
</ol></li>
{{/ patternTypeItems }}
{{# patternItems }}
<li><a href="patterns/{{ patternPath }}" class="sg-pop" data-patternpartial="{{ patternPartial }}">{{ patternName }}</a></li>
<li><a href="patterns/{{ patternPath }}" class="sg-pop {{# patternState }}sg-pattern-state {{ . }}{{/ patternState }}" data-patternpartial="{{ patternPartial }}">{{ patternName }}</a></li>
{{/ patternItems }}
</ol></li>
{{/ patternTypes }}

View File

@ -8,7 +8,7 @@
*/
var scriptLoader = {
run: function(js,cb,target) {
var s = document.getElementById(target+'-'+cb);
for (var i = 0; i < js.length; i++) {
@ -17,15 +17,11 @@
c.src = '../../'+src+'?'+cb;
if (typeof js[i] != "string") {
if (js[i].dep !== undefined) {
c.onload = function(dep) {
c.onload = function(dep,cb,target) {
return function() {
for (var k = 0; k < dep.length; k++) {
var d = document.createElement('script');
d.src = '../../'+dep[k]+'?'+cb;
s.parentNode.insertBefore(d,s);
}
scriptLoader.run(dep,cb,target);
}
}(js[i].dep);
}(js[i].dep,cb,target);
}
}
s.parentNode.insertBefore(c,s);
@ -50,7 +46,7 @@
(function() {
if (self != top) {
var cb = '{{ cacheBuster}}';
var js = [ "styleguide/js/postmessage.js", { "src": "data/annotations.js", "dep": [ "styleguide/js/annotations-pattern.js" ] }, "styleguide/js/code-pattern.js"];
var js = [ { "src": "styleguide/js/vendor/jwerty.js", "dep": [ "styleguide/js/postmessage.js", { "src": "data/annotations.js", "dep": [ "styleguide/js/annotations-pattern.js" ] }, "styleguide/js/code-pattern.js" ] } ];
scriptLoader.run(js,cb,'pl-js-insert');
}
})();

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -0,0 +1,34 @@
.sg-pattern-state:before {
margin-right: 4px;
content: "\2022";
display: inline-block;
margin-bottom: -4px;
font-size: 18px;
vertical-align: bottom;
}
.sg-nav .sg-pattern-state:before {
margin-top: -4px;
margin-bottom: 0;
margin-left: -4px;
height: 20px;
display: block;
float: left;
}
.sg-sub-nav .sg-pattern-state:before {
margin-left: -11px;
margin-right: 4px;
}
.inprogress:before {
color: #FF4136 !important;
}
.inreview:before {
color: #FFCC00 !important;
}
.complete:before {
color: #2ECC40 !important;
}

View File

@ -503,14 +503,16 @@
-o-transition: bottom 0.3s ease-out;
transition: bottom 0.3s ease-out; }
.sg-view-close {
width: 100%;
margin-bottom: -10px; }
.sg-view-close-btn {
color: #fff;
position: absolute;
top: 1em;
right: 1em;
text-transform: uppercase;
text-decoration: none;
text-align: right; }
text-align: right;
display: block; }
.has-annotation {
cursor: help !important;
@ -585,6 +587,56 @@
color: gray;
font-size: 1em; }
#sg-code-markup {
padding-top: 10px; }
#sg-code-tabs {
list-style: none;
margin: 0;
padding: 0; }
#sg-code-tabs li {
float: left;
background-color: #333;
font-size: 1.3em;
font-weight: bold;
padding: 5px 15px;
border-top: 2px solid #666;
margin-right: 2px;
cursor: pointer; }
.sg-code-title-active {
color: #bbb;
background-color: #272822 !important; }
div.clear {
clear: both; }
.sg-code-patternname {
color: #aaa; }
#sg-code-loader {
display: none;
position: absolute;
left: 45%;
top: 20%;
width: 150px;
padding: 10px;
text-align: center;
border-radius: 10px;
background-color: #000;
z-index: 100; }
.spinner {
height: 30px;
width: 30px;
margin-left: auto; margin-right: auto;
background-position: center center;
background-repeat: no-repeat;
background: url('../assets/spinner.gif');
border-radius: 50%;
opacity: .7; }
/* Pattern Lab icon fonts */
@font-face {
font-family: 'icons';

View File

@ -703,14 +703,17 @@ $animate-quick: 0.2s;
}
//Annotation and code view close button
.sg-view-close {
width: 100%;
margin-bottom: -10px;
}
.sg-view-close-btn {
color: #fff;
position: absolute;
top: 1em;
right: 1em;
text-transform: uppercase;
text-decoration: none;
text-align: right;
display: block;
}
//Visually emphasize annotated elements
@ -810,6 +813,63 @@ $animate-quick: 0.2s;
font-size: 1em;
}
#sg-code-markup {
padding-top: 10px;
}
#sg-code-tabs {
list-style: none;
margin: 0;
padding: 0;
}
#sg-code-tabs li {
float: left;
background-color: #333;
font-size: 1.3em;
font-weight: bold;
padding: 5px 15px;
border-top: 2px solid #666;
margin-right: 2px;
cursor: pointer;
}
.sg-code-title-active {
color: #bbb;
background-color: #272822 !important;
}
div.clear {
clear: both;
}
.sg-code-patternname {
color: #aaa;
}
#sg-code-loader {
display: none;
position: absolute;
left: 45%;
top: 20%;
width: 150px;
padding: 10px;
text-align: center;
border-radius: 10px;
background-color: #000;
z-index: 100;
}
.spinner {
height: 30px;
width: 30px;
margin-left: auto; margin-right: auto;
background-position: center center;
background-repeat: no-repeat;
background: url('../assets/spinner.gif');
border-radius: 50%;
opacity: .7;
}
/* Pattern Lab icon fonts */
@font-face {

View File

@ -288,3 +288,19 @@ window.onbeforeunload = function() {
var obj = JSON.stringify({ "commentOverlay": "off" });
parent.postMessage(obj,annotationsPattern.targetOrigin);
};
// tell the parent iframe that keys were pressed
// toggle the annotations panel
jwerty.key('ctrl+shift+a', function (e) {
var obj = JSON.stringify({ "keyPress": "ctrl+shift+a" });
parent.postMessage(obj,codePattern.targetOrigin);
return false;
});
// close the annotations panel if using escape
jwerty.key('esc', function (e) {
var obj = JSON.stringify({ "keyPress": "esc" });
parent.postMessage(obj,codePattern.targetOrigin);
return false;
});

View File

@ -10,7 +10,8 @@ var annotationsViewer = {
// set-up default sections
commentsActive: false,
targetOrigin: (window.location.protocol === "file:") ? "*" : window.location.protocol+"//"+window.location.host,
targetOrigin: (window.location.protocol === "file:") ? "*" : window.location.protocol+"//"+window.location.host,
moveToOnInit: 0,
/**
* add the onclick handler to the annotations link in the main nav
@ -23,13 +24,6 @@ var annotationsViewer = {
e.preventDefault();
// make sure the code view overlay is off before showing the annotations view
$('#sg-t-code').removeClass('active');
codeViewer.codeActive = false;
var obj = JSON.stringify({ "codeToggle": "off" });
document.getElementById('sg-viewport').contentWindow.postMessage(obj,annotationsViewer.targetOrigin);
codeViewer.slideCode(999);
// remove the class from the "eye" nav item
$('#sg-t-toggle').removeClass('active');
@ -41,6 +35,15 @@ var annotationsViewer = {
// initialize the annotations viewer
annotationsViewer.commentContainerInit();
// load the query strings in case code view has to show by default
var queryStringVars = urlHandler.getRequestVars();
if ((queryStringVars.view !== undefined) && ((queryStringVars.view === "annotations") || (queryStringVars.view === "a"))) {
annotationsViewer.openComments();
if (queryStringVars.number !== undefined) {
annotationsViewer.moveToOnInit = queryStringVars.number;
}
}
},
/**
@ -60,9 +63,20 @@ var annotationsViewer = {
* open the annotations panel
*/
openComments: function() {
annotationsViewer.commentsActive = true;
// make sure the code view overlay is off before showing the annotations view
$('#sg-t-code').removeClass('active');
codeViewer.codeActive = false;
var obj = JSON.stringify({ "codeToggle": "off" });
document.getElementById('sg-viewport').contentWindow.postMessage(obj,annotationsViewer.targetOrigin);
codeViewer.slideCode(999);
// tell the iframe annotation view has been turned on
var obj = JSON.stringify({ "commentToggle": "on" });
document.getElementById('sg-viewport').contentWindow.postMessage(obj,annotationsViewer.targetOrigin);
// note that it's turned on in the viewer
annotationsViewer.commentsActive = true;
$('#sg-t-annotations').addClass('active');
},
@ -107,6 +121,16 @@ var annotationsViewer = {
$('#sg-annotation-container').css('bottom',-pos);
},
/**
* moves to a particular item in the viewer
*/
moveTo: function(number) {
if (document.getElementById("annotation-"+number) !== undefined) {
var top = document.getElementById("annotation-"+number).offsetTop;
$('#sg-annotation-container').animate({scrollTop: top - 10}, 600);
}
},
/**
* when turning on or switching between patterns with annotations view on make sure we get
* the annotations from from the pattern via post message
@ -173,6 +197,11 @@ var annotationsViewer = {
// slide the comment section into view
annotationsViewer.slideComment(0);
if (annotationsViewer.moveToOnInit != "0") {
annotationsViewer.moveTo(annotationsViewer.moveToOnInit);
annotationsViewer.moveToOnInit = "0";
}
},
/**
@ -198,8 +227,17 @@ var annotationsViewer = {
} else if (data.annotationState !== undefined) {
document.getElementById("annotation-state-"+data.displayNumber).innerHTML = (data.annotationState == true) ? "" : " hidden";
} else if (data.displaynumber !== undefined) {
var top = document.getElementById("annotation-"+data.displaynumber).offsetTop;
$('#sg-annotation-container').animate({scrollTop: top - 10}, 600);
annotationsViewer.moveTo(data.displaynumber);
} else if (data.keyPress !== undefined) {
if (data.keyPress == 'ctrl+shift+a') {
annotationsViewer.toggleComments();
return false;
} else if (data.keyPress == 'esc') {
if (annotationsViewer.commentsActive) {
annotationsViewer.closeComments();
return false;
}
}
}
}
@ -224,7 +262,7 @@ $('#sg-view li a').click(function() {
});
// toggle the annotations panel
jwerty.key('cmd+shift+a/ctrl+shift+a', function (e) {
jwerty.key('ctrl+shift+a', function (e) {
annotationsViewer.toggleComments();
return false;
});

View File

@ -78,4 +78,41 @@ window.addEventListener("message", codePattern.receiveIframeMessage, false);
window.onbeforeunload = function() {
var obj = JSON.stringify({ "codeOverlay": "off" });
parent.postMessage(obj,codePattern.targetOrigin);
};
};
// tell the parent iframe that keys were pressed
// toggle the code panel
jwerty.key('ctrl+shift+c', function (e) {
var obj = JSON.stringify({ "keyPress": "ctrl+shift+c" });
parent.postMessage(obj,codePattern.targetOrigin);
return false;
});
// when the code panel is open hijack cmd+a so that it only selects the code view
jwerty.key('cmd+a/ctrl+a', function (e) {
var obj = JSON.stringify({ "keyPress": "cmd+a" });
parent.postMessage(obj,codePattern.targetOrigin);
return false;
});
// open the mustache panel
jwerty.key('ctrl+shift+u', function (e) {
var obj = JSON.stringify({ "keyPress": "ctrl+shift+u" });
parent.postMessage(obj,codePattern.targetOrigin);
return false;
});
// open the html panel
jwerty.key('ctrl+shift+h', function (e) {
var obj = JSON.stringify({ "keyPress": "ctrl+shift+h" });
parent.postMessage(obj,codePattern.targetOrigin);
return false;
});
// close the code panel if using escape
jwerty.key('esc', function (e) {
var obj = JSON.stringify({ "keyPress": "esc" });
parent.postMessage(obj,codePattern.targetOrigin);
return false;
});

View File

@ -14,7 +14,9 @@ var codeViewer = {
encoded: "",
mustache: "",
css: "",
ids: { "e": "#sg-code-title-html", "m": "#sg-code-title-mustache", "c": "#sg-code-title-css" },
targetOrigin: (window.location.protocol === "file:") ? "*" : window.location.protocol+"//"+window.location.host,
copyOnInit: false,
/**
* add the onclick handler to the code link in the main nav
@ -29,13 +31,6 @@ var codeViewer = {
e.preventDefault();
// make sure the annotations overlay is off before showing code view
$('#sg-t-annotations').removeClass('active');
annotationsViewer.commentsActive = false;
var obj = JSON.stringify({ "commentToggle": "off" });
document.getElementById('sg-viewport').contentWindow.postMessage(obj,codeViewer.targetOrigin);
annotationsViewer.slideComment(999);
// remove the class from the "eye" nav item
$('#sg-t-toggle').removeClass('active');
@ -51,6 +46,13 @@ var codeViewer = {
// initialize the code viewer
codeViewer.codeContainerInit();
// load the query strings in case code view has to show by default
var queryStringVars = urlHandler.getRequestVars();
if ((queryStringVars.view !== undefined) && ((queryStringVars.view === "code") || (queryStringVars.view === "c"))) {
codeViewer.copyOnInit = ((queryStringVars.copy !== undefined) && (queryStringVars.copy === "true")) ? true : false;
codeViewer.openCode();
}
},
/**
@ -70,10 +72,22 @@ var codeViewer = {
* after clicking the code view link open the panel
*/
openCode: function() {
// make sure the annotations overlay is off before showing code view
$('#sg-t-annotations').removeClass('active');
annotationsViewer.commentsActive = false;
var obj = JSON.stringify({ "commentToggle": "off" });
document.getElementById('sg-viewport').contentWindow.postMessage(obj,codeViewer.targetOrigin);
annotationsViewer.slideComment(999);
// tell the iframe code view has been turned on
var obj = JSON.stringify({ "codeToggle": "on" });
document.getElementById('sg-viewport').contentWindow.postMessage(obj,codeViewer.targetOrigin);
// note it's turned on in the viewer
codeViewer.codeActive = true;
$('#sg-t-code').addClass('active');
},
/**
@ -105,23 +119,17 @@ var codeViewer = {
});
// make sure the click events are handled on the HTML tab
$('#sg-code-title-html').click(function() {
$('.sg-code-title-active').removeClass('sg-code-title-active');
$(this).toggleClass("sg-code-title-active");
$(codeViewer.ids["e"]).click(function() {
codeViewer.swapCode("e");
});
// make sure the click events are handled on the Mustache tab
$('#sg-code-title-mustache').click(function() {
$('.sg-code-title-active').removeClass('sg-code-title-active');
$(this).toggleClass("sg-code-title-active");
$(codeViewer.ids["m"]).click(function() {
codeViewer.swapCode("m");
});
// make sure the click events are handled on the CSS tab
$('#sg-code-title-css').click(function() {
$('.sg-code-title-active').removeClass('sg-code-title-active');
$(this).toggleClass("sg-code-title-active");
$(codeViewer.ids["c"]).click(function() {
codeViewer.swapCode("c");
});
@ -131,6 +139,8 @@ var codeViewer = {
* depending on what tab is clicked this swaps out the code container. makes sure prism highlight is added.
*/
swapCode: function(type) {
codeViewer.clearSelection();
var fill = "";
var className = (type == "c") ? "css" : "markup";
$("#sg-code-fill").removeClass().addClass("language-"+className);
@ -144,6 +154,34 @@ var codeViewer = {
$("#sg-code-fill").html(fill).text();
codeViewer.tabActive = type;
Prism.highlightElement(document.getElementById("sg-code-fill"));
$('.sg-code-title-active').removeClass('sg-code-title-active');
$(codeViewer.ids[type]).toggleClass("sg-code-title-active");
},
/**
* select the code where using cmd+a/ctrl+a
*/
selectCode: function() {
if (codeViewer.codeActive) {
selection = window.getSelection();
range = document.createRange();
range.selectNodeContents(document.getElementById("sg-code-fill"));
selection.removeAllRanges();
selection.addRange(range);
}
},
/**
* clear any selection of code when swapping tabs or opening a new pattern
*/
clearSelection: function() {
if (codeViewer.codeActive) {
if (window.getSelection().empty) {
window.getSelection().empty();
} else if (window.getSelection().removeAllRanges) {
window.getSelection().removeAllRanges();
}
}
},
/**
@ -205,6 +243,10 @@ var codeViewer = {
$("#sg-code-fill").removeClass().addClass("language-"+className);
$("#sg-code-fill").html(code).text();
Prism.highlightElement(document.getElementById("sg-code-fill"));
if (codeViewer.copyOnInit) {
codeViewer.selectCode();
codeViewer.copyOnInit = false;
}
},
/**
@ -213,47 +255,47 @@ var codeViewer = {
*/
updateCode: function(lineage,lineageR,patternPartial,cssEnabled) {
// clear any selections that might have been made
codeViewer.clearSelection();
// draw lineage
if (lineage.length !== 0) {
var lineageList = "";
$("#sg-code-lineage").css("display","block");
for (var i = 0; i < lineage.length; i++) {
lineageList += (i === 0) ? "" : ", ";
lineageList += "<a href='"+lineage[i].lineagePath+"' data-patternPartial='"+lineage[i].lineagePattern+"'>"+lineage[i].lineagePattern+"</a>";
var cssClass = (lineage[i].lineageState != undefined) ? "sg-pattern-state "+lineage[i].lineageState : "";
lineageList += "<a href='"+lineage[i].lineagePath+"' class='"+cssClass+"' data-patternPartial='"+lineage[i].lineagePattern+"'>"+lineage[i].lineagePattern+"</a>";
}
$("#sg-code-lineage-fill").html(lineageList);
} else {
$("#sg-code-lineage").css("display","none");
}
// when clicking on a lineage item change the iframe source
$('#sg-code-lineage-fill a').on("click", function(e){
e.preventDefault();
var obj = JSON.stringify({ "path": urlHandler.getFileName($(this).attr("data-patternpartial")) });
document.getElementById("sg-viewport").contentWindow.postMessage(obj,codeViewer.targetOrigin);
});
// draw reverse lineage
if (lineageR.length !== 0) {
var lineageRList = "";
$("#sg-code-lineager").css("display","block");
for (var i = 0; i < lineageR.length; i++) {
lineageRList += (i === 0) ? "" : ", ";
lineageRList += "<a href='"+lineageR[i].lineagePath+"' data-patternPartial='"+lineageR[i].lineagePattern+"'>"+lineageR[i].lineagePattern+"</a>";
var cssClass = (lineageR[i].lineageState != undefined) ? "sg-pattern-state "+lineageR[i].lineageState : "";
lineageRList += "<a href='"+lineageR[i].lineagePath+"' class='"+cssClass+"' data-patternPartial='"+lineageR[i].lineagePattern+"'>"+lineageR[i].lineagePattern+"</a>";
}
$("#sg-code-lineager-fill").html(lineageRList);
} else {
$("#sg-code-lineager").css("display","none");
}
// when clicking on a reverse lineage item change the iframe source
$('#sg-code-lineager-fill a').on("click", function(e){
// when clicking on a lineage item change the iframe source
$('#sg-code-lineage-fill a, #sg-code-lineager-fill a').on("click", function(e){
e.preventDefault();
var obj = JSON.stringify( { "path": urlHandler.getFileName($(this).attr("data-patternpartial")) });
$("#sg-code-loader").css("display","block");
var obj = JSON.stringify({ "path": urlHandler.getFileName($(this).attr("data-patternpartial")) });
document.getElementById("sg-viewport").contentWindow.postMessage(obj,codeViewer.targetOrigin);
});
$('#sg-code-lineage-patternname, #sg-code-lineager-patternname').html(patternPartial);
// get the file name of the pattern so we can get the various editions of the code that can show in code view
var fileName = urlHandler.getFileName(patternPartial);
@ -279,7 +321,9 @@ var codeViewer = {
// move the code into view
codeViewer.slideCode(0);
$("#sg-code-loader").css("display","none");
},
/**
@ -296,13 +340,36 @@ var codeViewer = {
return;
}
// if the message contains the codeOverlay attribute act on it as appropriate
// switch based on stuff related to the postmessage
if (data.codeOverlay !== undefined) {
if (data.codeOverlay === "on") {
codeViewer.updateCode(data.lineage,data.lineageR,data.codePatternPartial,data.cssEnabled);
} else {
codeViewer.slideCode($('#sg-code-container').outerHeight());
}
} else if (data.keyPress !== undefined) {
if (data.keyPress == 'ctrl+shift+c') {
codeViewer.toggleCode();
return false;
} else if (data.keyPress == 'cmd+a') {
codeViewer.selectCode();
return false;
} else if (data.keyPress == 'ctrl+shift+u') {
if (codeViewer.codeActive) {
codeViewer.swapCode("m");
return false;
}
} else if (data.keyPress == 'ctrl+shift+h') {
if (codeViewer.codeActive) {
codeViewer.swapCode("h");
return false;
}
} else if (data.keyPress == 'esc') {
if (codeViewer.codeActive) {
codeViewer.closeCode();
return false;
}
}
}
}
@ -322,19 +389,29 @@ $('#sg-viewport').load(function() {
});
// toggle the code panel
jwerty.key('cmd+shift+c/ctrl+shift+c', function (e) {
jwerty.key('ctrl+shift+c', function (e) {
codeViewer.toggleCode();
return false;
});
// when the code panel is open hijack cmd+a so that it only selects the code view
jwerty.key('cmd+a/ctrl+a', function (e) {
codeViewer.selectCode();
return false;
});
// open the mustache panel
jwerty.key('ctrl+shift+u', function (e) {
if (codeViewer.codeActive) {
selection = window.getSelection();
range = document.createRange();
range.selectNodeContents(document.getElementById("sg-code-fill"));
selection.removeAllRanges();
selection.addRange(range);
codeViewer.swapCode("m");
return false;
}
});
// open the html panel
jwerty.key('ctrl+shift+h', function (e) {
if (codeViewer.codeActive) {
codeViewer.swapCode("e");
return false;
}
});

View File

@ -38,6 +38,32 @@ if (self != top) {
};
}
// bind the keyboard shortcuts for various viewport resizings
var keys = [ "s", "m", "l", "d", "h" ];
for (var i = 0; i < keys.length; i++) {
jwerty.key('ctrl+shift+'+keys[i], function (k,t) {
return function(e) {
var obj = JSON.stringify({ "keyPress": "ctrl+shift+"+k });
parent.postMessage(obj,t);
return false;
}
}(keys[i],targetOrigin));
}
// bind the keyboard shortcuts for mqs
var i = 0;
while (i < 10) {
jwerty.key('ctrl+shift+'+i, function (k,t) {
return function(e) {
var targetOrigin = (window.location.protocol == "file:") ? "*" : window.location.protocol+"//"+window.location.host;
var obj = JSON.stringify({ "keyPress": "ctrl+shift+"+k });
parent.postMessage(obj,t);
return false;
}
}(i,targetOrigin));
i++;
}
}
// if there are clicks on the iframe make sure the nav in the iframe parent closes

View File

@ -85,7 +85,7 @@
goSmall();
});
jwerty.key('cmd+shift+s/ctrl+shift+s', function(e) {
jwerty.key('ctrl+shift+s', function(e) {
goSmall();
return false;
});
@ -102,7 +102,7 @@
goMedium();
});
jwerty.key('cmd+shift+m/ctrl+shift+m', function(e) {
jwerty.key('ctrl+shift+m', function(e) {
goLarge();
return false;
});
@ -119,7 +119,7 @@
goLarge();
});
jwerty.key('cmd+shift+l/ctrl+shift+l', function(e) {
jwerty.key('ctrl+shift+l', function(e) {
goLarge();
return false;
});
@ -169,7 +169,7 @@
discoID = setInterval(disco, 800);
}
jwerty.key('cmd+shift+d/ctrl+shift+d', function(e) {
jwerty.key('ctrl+shift+d', function(e) {
if (!discoMode) {
startDisco();
} else {
@ -213,7 +213,7 @@
}
// start hay from a keyboard shortcut
jwerty.key('cmd+shift+h/ctrl+shift+h', function(e) {
jwerty.key('ctrl+shift+h', function(e) {
if (hayMode) {
startHay();
} else {
@ -273,8 +273,11 @@
});
// handle the MQ click
var mqs = [];
$('#sg-mq a').each(function(i) {
mqs.push($(this).html());
// bind the click
$(this).on("click", function(i,k) {
return function(e) {
@ -565,6 +568,35 @@
// reset the defaults
urlHandler.skipBack = false;
} else if (data.keyPress !== undefined) {
if (data.keyPress == 'ctrl+shift+s') {
goSmall();
} else if (data.keyPress == 'ctrl+shift+m') {
goMedium();
} else if (data.keyPress == 'ctrl+shift+l') {
goLarge();
} else if (data.keyPress == 'ctrl+shift+d') {
if (!discoMode) {
startDisco();
} else {
killDisco();
}
} else if (data.keyPress == 'ctrl+shift+h') {
if (hayMode) {
startHay();
} else {
killHay();
}
} else if (data.keyPress == 'ctrl+shift+0') {
sizeiframe(320,true);
} else if (found = data.keyPress.match(/ctrl\+shift\+([1-9])/)) {
var val = mqs[(found[1]-1)];
var type = (val.indexOf("px") !== -1) ? "px" : "em";
val = val.replace(type,"");
var width = (type === "px") ? val*1 : val*$bodySize;
sizeiframe(width,true);
}
return false;
}
}
window.addEventListener("message", receiveIframeMessage, false);