/** * Sets the required layout for a component to anchor another component or * be anchored. * * @param Component $component * @access public */ public function set_anchor_layout_for($component) { // Are we anchoring left or right? $position = null; switch ($component->get_anchor_position()) { case Component::ANCHOR_NONE: return; case Component::ANCHOR_LEFT: $position = 'left'; break; case Component::ANCHOR_RIGHT: $position = 'right'; break; case Component::ANCHOR_AUTO: // The alignment position is the opposite of the body_orientation // setting. In the case of centered body orientation, use left alignment. // This behaviour was chosen by design. if ('left' == $this->get_setting('body_orientation')) { $position = 'right'; } else { $position = 'left'; } break; } $layout_name = "anchor-layout-{$position}"; if (!$this->layout_exists($layout_name)) { // Cache settings $alignment_offset = $this->get_setting('alignment_offset'); $body_column_span = $this->get_setting('body_column_span'); $layout_columns = $this->get_setting('layout_columns'); // Find out the starting column. This is easy enough if we are anchoring // left, but for right side alignment, we have to make some math :) $col_start = 0; if ('right' == $position) { if ($component->is_anchor_target()) { $col_start = $layout_columns - $body_column_span + $alignment_offset; } else { $col_start = $body_column_span - $alignment_offset; } } // Find the column span. For the target element, let's use the same // column span as the Body component, that is, 5 columns, minus the // defined offset. The element to be anchored uses the remaining space. $col_span = 0; if ($component->is_anchor_target()) { $col_span = $body_column_span - $alignment_offset; } else { $col_span = $layout_columns - $body_column_span + $alignment_offset; } // Finally, register the layout $this->register_layout($layout_name, array('columnStart' => $col_start, 'columnSpan' => $col_span)); } $component->set_json('layout', $layout_name); // TODO: Use an animation manager $component->set_json('animation', array('type' => 'fade_in', 'userControllable' => true, 'initialAlpha' => 0.0)); }
/** * This component needs to ensure it didn't end up with empty content. * This will go through sanitize_text_field later as part of the assembled JSON. * Therefore, tags aren't valid but we need to catch them now * or we could encounter a parsing error when it's already too late. * * We also can't do this sooner, such as in build, because at that point * the component could still contain nested, valid tags. * * We don't want to modify the JSON since it will still undergo further processing. * We only want to check if, on its own, this component would end up empty. * * @access public * @return array */ public function to_array() { $sanitized_text = sanitize_text_field($this->json['text']); if (empty($sanitized_text)) { return new \WP_Error('invalid', __('empty body component', 'apple-news')); } else { return parent::to_array(); } }
/** * Given two components, anchor the first one to the second. * * @param Component $component * @param Component $target_component * @access private */ private function anchor_together($component, $target_component) { if ($target_component->is_anchor_target()) { return; } $component->set_json('anchor', array('targetComponentIdentifier' => $target_component->uid(), 'targetAnchorPosition' => 'center', 'rangeStart' => 0, 'rangeLength' => 1)); // Given $component, find out the opposite position. $other_position = null; if (Component::ANCHOR_AUTO == $component->get_anchor_position()) { $other_position = 'left' == $this->get_setting('body_orientation') ? Component::ANCHOR_LEFT : Component::ANCHOR_RIGHT; } else { $other_position = Component::ANCHOR_LEFT == $component->get_anchor_position() ? Component::ANCHOR_RIGHT : Component::ANCHOR_LEFT; } $target_component->set_anchor_position($other_position); // The anchor method adds the required layout, thus making the actual // anchoring. This must be called after using the UID, because we need to // distinguish target components from anchor ones and components with // UIDs are always anchor targets. $target_component->anchor(); $component->anchor(); }
/** * Given two components, anchor the first one to the second. * * @param Component $component * @param Component $target_component * @access private */ private function anchor_together($component, $target_component) { if ($target_component->is_anchor_target()) { return; } // Get the component's anchor settings, if set $anchor_json = $component->get_json('anchor'); // If the component doesn't have it's own anchor settings, use the defaults. if (empty($anchor_json)) { $anchor_json = array('targetAnchorPosition' => 'center', 'rangeStart' => 0, 'rangeLength' => 1); } // Regardless of what the component class specifies, // add the targetComponentIdentifier here. // There's no way for the class to know what this is before this point. $anchor_json['targetComponentIdentifier'] = $target_component->uid(); // Add the JSON back to the component $component->set_json('anchor', $anchor_json); // Given $component, find out the opposite position. $other_position = null; if (Component::ANCHOR_AUTO == $component->get_anchor_position()) { $other_position = 'left' == $this->get_setting('body_orientation') ? Component::ANCHOR_LEFT : Component::ANCHOR_RIGHT; } else { $other_position = Component::ANCHOR_LEFT == $component->get_anchor_position() ? Component::ANCHOR_RIGHT : Component::ANCHOR_LEFT; } $target_component->set_anchor_position($other_position); // The anchor method adds the required layout, thus making the actual // anchoring. This must be called after using the UID, because we need to // distinguish target components from anchor ones and components with // UIDs are always anchor targets. $target_component->anchor(); $component->anchor(); }